Dynamic object creation with Retrofit - android

I am not that skilled with Retrofit library and I ran into a problem that i don't know how to handle without restructuring the whole project.
Basically, i have two responses that are very similar, but my code only handles one response.
Here are the responses and what i did, so tell me if there is any way to do this...
{
"cv":[
{
"id":46,
"name":"Ciriculum Vitae",
"description":"Lorem ipsum description is the best description one can write down",
"file":"1482915089-test-test-cv1.pdf",
"file_url":"http://xxxyy/file/46/1482915089-test-test-cv1.pdf",
"type":"cv"
},
...
],
"diploma":[
{
"id":52,
"name":"dasdasdasdsa",
"description":"Random description",
"institution_name":"hello",
"completed_date":"12.12.2016.",
"file":"1482918005-test-test-dasdasdasdsa.pdf",
"file_url":"http://xxxyy/file/52/1482918005-test-test-dasdasdasdsa.pdf",
"type":"diploma"
}
],
...
"certification":[
{
"id":50,
"name":"Certificate of Greatness",
"description":"I have been great at many things so everybody diecided to give me a certificate for it.",
"institution_name":"Certification 3",
"validation_date":"10.06.2017.",
"file":"1482917772-test-test-dasdasdasdsa.pdf",
"file_url":"http://xxxyy/file/50/1482917772-test-test-dasdasdasdsa.pdf",
"type":"certification"
}
],
...
}
Okay this is just a sample, but you can clearly see that these are some documents that have their types. There are 17 types of documents each with different fields.
Logically, I've created 17 different models cv model, diploma model, etc...
The problem arises later in the project when i want to fetch documents that are related to a single candidate, the response then is like so:
Response2
"documents": [
{
"id": 46,
"name": "Ciriculum Vitae",
"type": "cv",
"description": "Lorem ipsum description is the best description one can write down",
"file": "1482915089-test-test-cv1.pdf",
"file_url": "http://xxxyy/file/46/1482915089-test-test-cv1.pdf"
},
{
"id":52,
"name":"dasdasdasdsa",
"description":"Random description",
"institution_name":"hello",
"completed_date":"12.12.2016.",
"file":"1482918005-test-test-dasdasdasdsa.pdf",
"file_url":"http://xxxyy/file/52/1482918005-test-test-dasdasdasdsa.pdf",
"type":"diploma"
},
{
"id": 50,
"name": "Certificate of Greatness",
"type": "certification",
"description": "I have been great at many things so everybody diecided to give me a certificate for it.",
"file": "1482917772-test-test-dasdasdasdsa.pdf",
"file_url": "http://xxxyy/file/50/1482917772-test-test-dasdasdasdsa.pdf"
}
]
}
Now obviously the field 'type' is the type of object that needs to be created. But so far i don't know how to make my models fit into this 2nd response.
What should i do here, guys?
In case you're wondering what my code looks like, here it is...
#SerializedName("cv")
#Expose
private List<Cv> cv = null;
...
#SerializedName("diploma")
#Expose
private List<Diploma> diploma = null;
...
#SerializedName("certification")
#Expose
private List<Certification> certification = null;
EDIT
Actually what i wanted to do is create object dependent on the 'type' parameter and fill it with info i get from the response.
How will i go about doing this?

Related

Query problem using sembast (NoSql) with flutter

I'm very new to NoSql databases, and I just want to ask you an easy question about the use of sembast! I'm developing a very simple app with flutter, and I want to get the object inside the array "list" with the "name" equal to 1.
{
"id": 12345,
"list": [{
"name": 1,
"element": [{
"nameItem": "a"
}, {
"nameItem": "b"
}]
}, {
"name": 2,
"element": []
}, {
"name": 3,
"element": []
}]
}
So I want to make a query that retrieves me this information:
{
"name": 1,
"element": [{
"nameItem": "a"
}, {
"nameItem": "b"
}]
}
I've written this code, but it doesn't work: I don't understand how to make a query with a subtag as a key in the json tree.
Future<List<ElementList>> getElementFromList(int name) async{
final finder = Finder(filter: Filter.equals("name", name));
final recordSnapshot = await _elementList.find(await _db, finder: finder);
return recordSnapshot.map((snapshot){
final elementObj = ElementList.fromJson(snapshot.value);
return elementObj;
}).toList();
}
this returns me []. How can I solve the problem?
Thank you in advance!
Sembast queries allow to filter records, not part of a record. If the object you mention is a whole record, you can:
use custom filter to perform the lookup yourself for each record in the database (checking each item in the list field`)
when a record is retrieved, extract the item (doing a similar Map/List manipulation)
See an issue with a complex filtering

REST Api JSON response with field changing

I have to consume a JSON Rest api (for mobile). This api returns a field that is changing like so : (string, int, null, array, object or array of object)
{"field": [{"id": 12, "value": "string value"}]} //array of object
{"field": 12345} //int
{"field": "string"} //string
{"field": {"id": 1, "value": "I'm an object now"}} //object
{"field": ["array", "of", "string"]} //array of string
I may be possible to change the server response to be able to do some standardisation, which could be great! Right now I had to create an adapter (with GSON) but this solution have is limitations, especially with performances and maintainability..
How could I create a good response that will be easy to understand and use?
You could find some relevant information here :
http://jsonapi.org/format/#introduction
https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
There isn't any json specifications, everybody can do whatever they want. But there are some best practices.
The simple & useful structure is as below:
{
"success": true,
"message": "It is done",
"data": {
"id": 123,
"value": "string",
"object":{
"object_value":"I'm an object now"
},
"array_object":[ {"key1":"value1"},{"key2":"value2"},{"key3":"value3"} ]
},
"string": "Hello World"
}

Firebase add item to array dynamically

I am trying to make some kind of comments using Firebase for Android.
Just have one question, are there any way to add new items to array?
For example, if I have such kind of object
If I am trying to push, it will convert it to map
And I don't want to overwrite this object each time, because I will have multiuser support and it will fail at some point.
And I am trying to do it as a List to do not create DataTransferObjects for my models, and to support auto parsing using firebase.
Thanks! If there will be no ideas will go with creating Maps, actually.
My ObjectModel:
public class Company implements Parcelable {
private String id;
private String name;
private String description;
private List<Comment> comments;
}
Code for pushing item:
final DatabaseReference ref = companiesRef.child(companyId).child(NODE_COMMENTS).push();
return Single.create(e -> ref.setValue(comment)
.addOnCompleteListener(task -> {
e.onSuccess(task.isSuccessful());
}));
This is how it works, look at the example below I have stored "0" as my first commentID and "1" as my second commentID. As you can see, I stored the lastCommentID as the commentID for the last comment in the lists.
{
"comments": {
"0": {
"text": "mycomment",
"time": "142351516"
},
"1": {
"text": "secondcomment",
"time": "153426564"
}
}
"lastCommentId": "1"
}
So whenever you want to add new comment to the firebase you have to retrieve the lastCommentID first as a string and convert it to integer(E.g. 1) then add 1 to the value(E.g. 2) so that when you save the next comment it won't override the previous version.
Note that you have replace lastCommentID each time you add comment to the database.
{
"comments": {
"0": {
"text": "mycomment",
"time": "142351516"
},
"1": {
"text": "secondcomment",
"time": "153426564"
},
"2": {
"text": "thirdcomment",
"time": "153426564"
}
}
"lastCommentId": "2"
}
You do not need to have a Model Class to write in Firebase, you can parse a JSON to Java Objects dinamically with Jackson and push it into Firebase.
You can parse a JSON as Java Objects with Jackson
. For example you can obtain: Object, List, Hashmap, Integer, String,
etc. without POJO classes.
To see more please visit this answer

Jackson deserializing JSON into multiple POJOs

Hi I have following JSON
{
"code": 0,
"response": {
"userObject": {
"User": {
"id": "355660",
"first_name": "Dummy",
"last_name": "dummy",
"email": "dumb#email.com",
"birthday": "2012-05-07",
"created": "2012-08-21 06:41:05",
"modified": "2012-08-21 06:41:05",
"image_url": null,
},
"Location": {
"id": "273550",
"name": "New York City",
"asciiName": "New York City",
"lat": "40.714272",
"lon": "-74.005966",
"geoname_modified": "2011-11-08 00:00:00",
"timeZone": "America/New_York",
"countryName": "United States",
"state": "New York",
"created": "2012-07-12 12:11:01",
"modified": "2012-08-20 14:27:24"
}
}
}
}
I have two classes, one each for Location and User
I know that I can get the objects if I create nested class like
response
->UserObject
*User
*Location
But i don't want to create two extra classes for UserObject and response just for wrapping the two POJO's .
Is there any simpler way to do it??
I am using Jackson Parser with Spring for android
You can also do it in two steps, if you really want to avoid throw-away classes, like:
JsonNode tree = mapper.readTree(...);
User user = mapper.treeToValue(tree.path("response").path("userObject").get("User"), User.class);
Location loc = mapper.convertValue(tree.path("response").path("userObject").get("Location"), Location.class);
but yeah I might go with silly struct-classes instead:
static class Response {
public UserObject userObject;
}
static class UserObject {
public Location Location;
public User User;
}
since it really isn't much more code.
Rather than creating classes you could create arrays or use hashmap. Personally, I would just create the classes. I think that this give you more flexibility in your app, and will allow you to work with the objects with less hassle. I know it takes time to set them up, but once you do that, you can use ArrayList and you can parse the JSON quite a bit easier.

Android GSON: Parsing several different objects from the same response

I'm working on porting an iPhone app that relies heavily on JSON to Android.
One of the responses that has to be parsed is used to build the main screen. The JSON response for this contains 3 different objects, namely Icons, Header and Player. These are all contained within the object Home.
Icons and Player both contain an Array of items, the Header is just a single item.
Now I'm still a beginner when it comes to JSON, and I'm not quite sure how I should parse this response. Therefore I would like to know if I have the right idea before working myself into problems.
My idea is to create 4 different classes, one for Home, icons, Header and Player.
Home would contain an array of both Icons and Player, and an object of Header.
But I'm not sure if this is the correct way to do this.
The JSON response in questions is as followed: (Removed some objects due to the size of the response)
{
"Home": {
"Icon": [
{
"ScreenID": 533,
"ScreenIndex": 1,
"IconName": "mainIcon_news",
"Title": "News",
"FK_ModuleID": 6,
"FormID": 567,
"ModName": "News",
"MediaType": "",
"New_Icon": 0
},
{
"ScreenID": 528,
"ScreenIndex": 2,
"IconName": "mainIcon_music",
"Title": "Music",
"FK_ModuleID": 3,
"FormID": 562,
"ModName": "Media",
"MediaType": "Music",
"New_Icon": 0
}
],
"Header": [
{
"ModHomeRotationID": 183,
"image_url": "*****/Media/68/1216_5.jpg",
"flg_RotationEnabled": false,
"flg_RotateOnlyOnReturn": true,
"flg_RotationRandomize": false,
"flg_RotationDelayMS": 5000,
"flg_RotationDelayFadeMS": 3000,
"HomeRotationIndex": null
}
],
"Player": [
{
"MediaID": 1219,
"Track_Name": "***",
"song_url": "*****/Media/68/1219.mp3",
"song_remote_url": null,
"FileSize": 4700502
},
{
"MediaID": 1220,
"Track_Name": "**** ",
"song_url": "*****/Media/68/1220.mp3",
"song_remote_url": null,
"FileSize": 4350222
}
]
}
}
Could someone tell me if I'm in the right direction, and if not, what I should be doing instead?
I should mention, I'm using GSON to parse the JSON responses at the moment.
Thanks in advance
Yes you are right you need to create Four classes and need to initialize the values inside that class name..
Validate your Json using JSONLint :
Then try this sample Parsing JSON using GSON and One More

Categories

Resources