Parse JSON attribute "data" using gson and retrofit2 in fancy way - android

Well, I've seen alot of boilerplate code in my model classes when I need to parse json using GSON with Retrofit2. I would like to find out how to deal with it, because I'm pretty sure there is a way to make this look more elegant.
{
"data": [
{
"id": 2,
"price": 56,
"name": "Hello"
}
]
}
For parsing this json I would need to create 2 model classes. One would be for the inner object (id, price, name) and one would be Data.class which holds one attribute - List of this inner object.
It's totally okay to have different inner objects inside, but later on you will have many "Data.class" which has one attribute "data" which is List, but with different inner object type. How can I avoid this boiler-plate Data lookalike classes in my projects?
What I want:
Is to NOT create new Data class with "data" attribute changing inner object type whenever I create new "inner" object model class.

I had this problem and fix that with create one abstract class with name BaseResponse like this
public abstract class BaseResponseInterface2<T> {
#SerializedName("data")
private List<T> data;
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}
And use that like this in api service interface
#GET("/api/")
Call<BaseResponseInterface2<innerClass>> getResponse(
#Path("id") int id
);
Hope it help

Related

How to use continue as a parameter for a method

in the json file i receive as respone it contains a key "continue" and to create the model object for the response i have to use "continue" as a parameter in the method.
Activity
public object Model {
data class ResultOfContinue(val continue: Continue)
}
json
"batchcomplete": "",
"continue": {
"sroffset": 10,
"continue": "-||"
},
If you really wanna use keyword as a parameter. You can use like this :
data class ResultOfContinue(val `continue`: Continue) {
}

Is it possible to serialize and deserialize an object that contain an object as a variable in Firebase?

I am trying to structure my databases, and I was wondering if it's possible to deserialize an object from Firebase RealDatabase with the following structure.
public class Profile{
private String userID;
private TenantProfile tenant;
}
public class TenantProfile{
private String name;
private Room room;
}
public class Room{
private String town;
private int size;
}
Can the entire object Profile from Firebase be deserialized from a single query?
I just want to make sure that this is possible before refactoring my code and changing the references to the database.
Thanks in advance.
The Firebase database serializes/deserializes any public fields, and public properties that follow JavaBean naming conventions for getters and setters. Since the classes you show contain neither of those, they will not read or write any data.
If you mark the fields as public or add public getters/setters, then writing an instance of the Profile class will generate this JSON:
"userID": {
"tenant": {
"name": "the name",
"room": {
"town": "the town",
"size": 42
}
}
}
And that's also the format you'll need to have in the database to read the value back.

Does Retrofit support keypath on json parsing or something alike?

For example i have json looks like:
{
"data": [
{
"name": "one"
},
{
"name": "two"
}
]
}
For example i have object User with field name.
Is it possible write method which will parse data array to objects User?
something like
Call<List<User>> getUsers(#KeyPath("data"))
Now to do this, i need create a wrapper class something like
public class UsersWrapper {
#SerializeName("data")
public ArrayList<User> users;
}
and in service i do next
public interface Service {
#GET("users")
Call<UsersWrapper> getUsers()
}
But my all requests is just response with data but variable objects in array.
In this case i need create wrappers to any data requests. Pain :(
?
I'd do it this way:
Global class Wrapper<T> to parse the whole JSON
public class Wrapper<T> {
public List<T> data;
}
And User to parse actual array;
public class User {
public String name;
}
Then, the API interface:
#GET("/people")
Wrapper<User> getUsers();
And in DataSource class just do something like this:
#Override
public List<User> getUsers() {
Wrapper<User> usersWrapper = myApiInterface.getUsers();
return usersWrapper.data;
}
Upd1:
Another solution is to create custom JsonDeserializer (like described here) for List<User> type, register by registerTypeAdapter it with your custom Gson object and then you can deserialise your Json directly into List<User>. Though, this solution brings much more extra code and potential benefit is unclear for me.

Retrofit returns valid list but items members are null

I have a problem pretty much the same as this: retrofit returning valid json but pojo is empty
But my variables are not declared as static. The are all declared like:
#SerializedName("name")
#Expose
private String name;
I have tried removing the annotations, but that doesn't work.
what could be the problem?
EDIT:
Interface:
#GET("/MyController/MyAction/{name}")
void getSomeData(#Path("name") String name, Callback<List<DataItem>> cb);
Can you show me the actual received data(JSON or XML)? It seems that your callback structure is not matching with your data. For example, it would be possible that your data may have array that have a name, and you ignored it.
In my case, I declared like this,
void getList(#Path("data") String data,//
Callback<OrderList> callback);
OrderList is:
public class OrderList {
List<Order> order_list;
}
And my data is:
{
"order_list":
[
{ "id": "1001", "data": "a" },
{ "id": "1002", "data": "b" }
]
}
I mean, it seems that your data may have nested structure and your class may not matching with that.

JSONObject as class attribute storage/retrieval

In android, I'm using model classes with methods to handle the data manipulation. My data is brought in from webservices as json. I'm contemplating the possibility of using JSONObjects to store the values of class level attributes. But, I don't know of a way to use the JSONObj as the "holder" variable and create access methods. I don't want to predetermine these methods, as jsonRepository should hold the values, not always known at design time
For example, I'd like to have:
public class User {
private JSONObject jsonAttributes;
public User(String json) {
this.jsonAttributes= new JSONObject(json);
}
[IMPLICIT attribute access methods]
public string Prop1() returns jsonAttributes.getString("prop1");
public string Prop1(String newProp1) returns jsonAttributes.putString("prop1",newProp1);
public string Prop2() returns jsonRepository.getString("id");
public string Prop2(String newProp2) returns jsonAttributes.putString("prop2",newProp2);
....
from outside this class then, I would access the attributes simply...
User myUser = new User(someValidJson);
String myString = myUser.Prop1
Misguided? If not, how does one manage implicit property setting/getting?
As was mentioned in the comment above, why not create your user class, with all of the relevant memeber variables, and simply parse your JSON data in order to populate the ionformation in your user class.
There are a lot of ways you can do this, but I would consider using the builder pattern, as it is flexible, which could be useful if your JSON data changes in the future.

Categories

Resources