Cached complex/nested objects and querying them with Greendao Android - android

Ok this is the scenario, I have a complex object like this (see below) and it is downloaded and parsed using Retrofit. I generated the Java class (POJO) using GreenDao and everything is ok while the app is running: retrofit response body is as I want, I insert this response.body() to the DB and if I query in other activity this object is retrived by GreenDao with all the attributes setted (is the cached object).
The problem is when I clear all the caches or close the app and open it again, the list of the nested objects is null (see the second json below).
How can I solve this? Thanks in Advance
Json sent from the server
{
"id" : 91
"timestamp": 1487786669,
"groups": [
{
"id": "G1",
"name": "Some name",
"nextPaymentDate": "2017-06-01",
"totalAmount": 1000.00,
"overdraft": false,
"apoyaT": true
},
{
"id": "G2",
"name": "Other name",
"nextPaymentDate": "2017-06-02",
"totalAmount": 1000.00,
"overdraft": true,
"apoyaT": false
}
]
}
Json/JavaObject when the cache is cleared
{
"id": 91
"timestamp": 1487786669,
"groups": null
}
My GreenDao Generator
/* List Entity ***************************/
Entity list = schema.addEntity("List_p");
list.addIntProperty("id").primaryKey();
list.addLongProperty("timestamp");
/* Group Entity **************************/
Entity group = schema.addEntity("Group");
group.addStringProperty("id").primaryKey();
group.addStringProperty("name");
group.addStringProperty("nextPaymentDate");
group.addDoubleProperty("totalAmount");
group.addBooleanProperty("overdraft");
group.addBooleanProperty("apoyaT");
Property listId = group.addLongProperty("listId").getProperty();
list.addToMany(group, listId, "groups");

Related

Moshi - Skip a object if it contains a certain value

Suppose I have the following JSON -
{
"list": [
{
"name": "John",
"age": 20
},
{
"name": "Peter"
"age": 18
},
{
"name": "Jane",
"age": 21
}
]
}
Is there a way in moshi in which we can skip the list item where the name is "Peter"?
My issue is that I need to show a list of items only if they match with certain values (eg. "imageType" = "jpeg") provided in json and skip everything else. I am wondering if one can do the skipping at the json parsing level rather than somewhere in the business logic where I would have to run a for loop and go through every element again.

kotlinx.serialization - partial deserialization

I have a very large json file within my android app with the following struture:
[
{
"id": 123,
"data": {
...
}
},
{
"id": 456,
"data": {
...
}
},
...
]
Depending on the item selected in the UI, I need to deserialize only the item with the corresponding id, but right now I'm deserializing the whole file and then do the filter, which takes time and memory to just extract the id I need.
Is there a way to deserialize only the section I need?
I'm using kotlinx.serialization.

How to query filter json with Retrofit

I have api that return list of workers:
{
"items": [
{
"id": "e0fceffa-cef3-45f7-97c6-6be2e3705927",
"avatarUrl": "https://cdn.fakercloud.com/avatars/marrimo_128.jpg",
"firstName": "Dee",
"lastName": "Reichert",
"userTag": "LK",
"department": "back_office",
"position": "Technician",
"birthday": "2004-08-02",
"phone": "802-623-1785"
},
{
"id": "6712da93-2b1c-4ed3-a169-c69cf74c3291",
"avatarUrl": "https://cdn.fakercloud.com/avatars/alterchuca_128.jpg",
"firstName": "Kenton",
"lastName": "Fritsch",
"userTag": "AG",
"department": "analytics",
"position": "Orchestrator",
"birthday": "1976-06-14",
"phone": "651-313-1140"
},
....
]
}
I want to filter the response so that I only get information about a worker from a specific department.
I tried to do it like this:
interface WorkersApi {
#GET("users")
suspend fun getWorkers(
#Query("department") department: String
): Workers
}
But it return the same list without any filters. How can I filter the response so that I only get information about a worker from a specific department?
*Workers is just data class that hold only one field - list of items(workers)
What you tried to do changes the request to the server. It sends the department as query parameter with the request. If the server doesn't support this parameter nothing happens. I don't know if you work together with the people controlling the backend but you could discuss with them if they could add functionality for filtered results.
If instead, you want to filter the results after getting the full list from the server simply apply a filter on the list that you got.
you could do this on your Workers object
val department = "example"
val filteredList = workersObject.items.filter {it.department == department}

Deserializing different objects in JSON array (GSON)

The JSON result for getUsers I get from the server looks like this:
{
"result": [
{
"meta": {
"rows": "3"
}
},
{
"items": [
{
"id": "1",
"name": "Steve",
"age": "30"
},
{
"id": "2",
"name": "Mary",
"age": "29"
},
{
"id": "3",
"name": "Bill",
"age": "58"
}
]
}
]
}
How can I deserialize it by GSON in my android app (I'm using retrofit)?
I can't imagine any wrapper classes because of the different object types in result.
Any help would be appreciated!
For good example
Converting JSON to Java
Other way, you can convert your json to a java object
Please use org.json library http://www.json.org/java/index.html
Then, for example
json = new JSONObject(YOUR_JSON).getJSONObject("result");
JSONArray items = data.getJSONArray("items");
String name = items.getJSONObject(0).getString("name");
You can write a TypeAdapter for a type that will be (de)serialized to(from) array. You can even make it generic, so it will work with type like Pair<A, B>. Here is an example for non-generic type: https://github.com/cakoose/json-tuple-databinding-examples/blob/master/java/src/GsonEntryCustomizer.java — it (de)serializes Entry to(from array).
Disclaimer — I have not written nor tested that code, but it seems legit.
If you only encounter such problem once (like in your example), you may not bother making it generic, just write TypeAdapter for your specific pair of 2 different classes. The reading code is quite straightforward:
in.beginArray();
SomeClass1 info1 = gson.getAdapter(SomeClass1.class).read(in);
SomeClass2 info2 = gson.getAdapter(SomeClass2.class).read(in);
in.endArray();
return new SomeContainerClass(info1, info2);
(see https://github.com/cakoose/json-tuple-databinding-examples/blob/master/java/src/GsonEntryCustomizer.java#L52)

Deserialise JSON with dynamic field

I'm loading JSON with a completely dynamic field from an API using Retrofit on Android.
This is an example:
{
"success": true,
"messages": {
"success": [
"SUCCESS_MESSAGE"
],
"error": {
"specific_error": {
…
}
}
},
"session": {
"id": "fj4qewqrewq43fdsa",
"expire": null,
"YII_CSRF_TOKEN": "fda432fdafasd78978fdas"
},
"metadata": {…}
}
The structure of the messages object can change with every request. Sometimes there is the success field and sometimes not. Same goes for the error field. The error field especially can be an array but also an object with several other objects and fields inside.
Does it make sense to deserialise the messages field into different POJOs and if so how would I do that? Would it make more sense to keep the field as a JSON object and get values from the object when they are needed?

Categories

Resources