How to get arrays from JSON using retrofit in Android? - android

This is my JSON
[{
"user_name": "name",
"tags": ["p", "a", "py"],
"a": 3,
"b": 12,
"c": 4
},
{
"user_name": "name2",
"tags": ["p2", "a2", "py2"],
"a": 32,
"b": 122,
"c": 42
}]
I have no problems using retrofit to get all the other values, except tags. How do I do it?

If you provide some code of what you are actually using currently that would help us help you better. In any case since you mentioned you are doing these already I am assuming you have created the POJO class for this response with something like
public class YourResponse
{
private String a;
private String b;
private String c;
private String user_name;
private String[] tags;
....
}
Now when you write a call to the api, since its a list of this class' objects you should write as
Call<List<YourResponse>> call = ...
and similarly in callbacks etc. like call.enqueue(new Callback<List<YourResponse>>()......
Edit: Just noticed you mentioned your problem was only with getting the values for "tags" and not the response. Your question is already answered by #Mark Keen in his comment. -"tags should be a List<String>, or String[]"

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

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

Dynamic object creation with Retrofit

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?

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.

Parsing json file with gson

I have a problem creating a mapping for a json that i want to parse using json. It's very specific, its about a json file with a json array with objects in it.
my jsonfile starts like this:
[
{
"venue": {
"venue_seasons": [
{
"created_at": "2011-12-25T23:00:28Z",
"updated_at": "2011-12-28T15:13:53Z",
"start_timestamp": 1293840000,
"id": 337,
"end": "2011-12-24T00:00:00Z",
"enabled": true,
"start": "2011-01-01T00:00:00Z",
"season_openings": [ … ],
"end_timestamp": 1324684800
},
{ … }
],
"address": "someadress",
"city": "cityname",
"name": "name",
"created_at": "2011-03-31T07:55:33Z",
etcetera
}
"venue":{another venue
So first an array, than an object (venue) with a lot of objects in it (i removed most of them, because thats not important for my question), and some arrays (like season_openings).
My parsing code works like this, im using gson. The inputstream works fine.
Reader reader = new InputStreamReader(inputStream);
JsonResponse venueResponse = gson.fromJson(reader, JsonResponse.class);
List<Venues> results = venueResponse.venue;
with the class JsonResponse:
public class JsonResponse {
public List<Venues> venue;
}
and Venues.class:
public class Venues {
public List<VenueSeasons> venue_seasons;
#SerializedName("adress")
public String getAdress;
#SerializedName("city")
public String getCity;
#SerializedName("country")
public String getCountry; etcetera
}
But when i run this code i get an error:
Unable to start activity ComponentInfo{com.hera.android.JSON/com.hera.android.JSON.TestParser2Activity}: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2
Ofcourse i can read the error: it expects an objects but get an array. I varied a lot with different jsonresponse.class and even with putting the whole json array in a json object (what is not really a solution because i need to work with this type of jsonfile). But everytime i get this or a similar error.
I think I'm close to a solution, can anyone see what i just can't and give me a helping hand?
Thanks.
Try calling Gson like this:
List<Venues> venues = gson.fromJson(reader, new TypeToken<List<Venues>>() {}.getType());
This works because your JSON document is a List, not an object that has a list as one of its properties.

Categories

Resources