Is it possible to pass an absolute url dynamically at runtime to retrofit?
For instance, I access a Rest API that returns a list of users and for pagination an absolute url that should be used to retrieve more items:
{
"result": [
{
"id": 1,
"name": "Daniel"
},
{
"id": 2,
"name": "Michael"
},
{
"id": 3,
"name": "Chris"
}
],
"pagination": "http://www.foo.com/users?offset=3"
}
It seems that it's not supported in Retrofit https://github.com/square/retrofit/issues/333
Is there a workaround that works with just one single RestAdapter?
It seems this is possible. Instead of passing an url to the RestAdapter.Builder.setEndPoint, you can pass a subclass of Endpoint, which you can use to dynamically set your url before every request.
Related
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.
I am using Retrofit lib for API call in my Android application. My JSON is like this.
{"options": [
{
"type": "item",
"type_id": "19E9E453-64C6-41C9-BFB7-D6EFB8AF68B8",
"key": "ageRange",
"value": "Early 30s"
},
{
"type": "item",
"type_id": "19E9E453-64C6-41C9-BFB7-D6EFB8AF68B8",
"key": "colors",
"value": "Black, Red"
}
]}
Or
{"options": []}
My model code is:
#SerializedName("options")
#Expose
private ArrayList<OptionsDataModel> options;
So if options is not empty the code working fine but if options is empty I am getting error invalid item. So can any one help to solve this problem.
You can add a check in your response method for result.body != null before parsing your response to your object
In my server I have a table called Sync wich looks like that:
}
"name": "Sync",
"base": "PersistedModel",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {
"uuid": {
"type": "string"
},
"table": {
"type": "string"
},
"action": {
"type": "string"
},
"timeChanged": {
"type": "number"
}
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
and in my database I have the following records in this table:
Sync": {
"34": "{\"uuid\":\"287c6625-4a95-4e11-847e-ad13e98c75a2\",\"table\":\"Property\",\"action\":\"create\",\"timeChanged\":1466598611995,\"id\":34}",
"35": "{\"uuid\":\"287c6625-4a95-4e11-847e-ad13e98c75a2\",\"table\":\"Property\",\"action\":\"update\",\"timeChanged\":1466598625506,\"id\":35}",
"36": "{\"uuid\":\"176aa537-d000-496a-895c-315f608ce494\",\"table\":\"Property\",\"action\":\"update\",\"timeChanged\":1466598649119,\"id\":36}"
}
How to apply a filter to by #GET request and I get all of the records say with timeChanged attribute bigger than or equal to "1466598625506".
I did try that:
#GET("Syncs")
Call<List<Sync>> getAllSyncsAfterThisTimeStamp(#Query(("filter[where][timeChanged]=>")) long timeChanged);
but that returns an empty array "[]". Please, any ideas how to get this filtering done?
There can be solution to this on the server side. I don't think that retrofit alone will be able to accomplish this task.
You can write a logic on server side which takes a get argument as a number and returns all object greater than or equal to that number.
Corresponding to this server script, you can make requests where you can pass a query parameter and get the desired result. You cant run a database query from a get or post request.
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)
Just as the title says.. Is it possible to do this? Say I have a JSON array of something like this
{
"locations": [
{
"id": 1,
"loc": "miami"
},
{
"id": 2,
"loc": "manhattan"
},
{
"id": 3,
"loc": "lasVegas"
}
]
}
Sure, extend BaseAdapter and use the JSONArray as your backing model. However, it would be better (but by no means necessary) to convert it to a more "natural" representation in Java and use that instead.
you can convert the json to a java object. and bind the data.