I'm beginner in android (Kotlin).I am getting the Following json from the HTTP Response.
{
"status": 1,
"userDetails": [
{
"AL_ID": "2",
"User_Id": "admin",
"User_Password": "admin",
"Created_Date": "2020-07-30 11:23:55"
}
],
"lastlogin": "2020-08-20 12:29:47"
}
I want to get status value from this json. How to get it.
You can use the built-in JSONObject and do something as shown below.
val json = JSONObject(jsonString) // String instance holding the above json
val status = json.getInt("status")
Having said that, I'd recommend you to take a look at Gson (for JSON serialization and deserialization) and Retrofit (an HTTP client for Android).
I would suggest using Gson library too, for android development in kotlin.
Also I would suggest to have the same DATA classes in kotlin as in database. In that way you can map objects fromJson and toJson with one line of code.
I found article that explains in details how to use Gson library with kotlin.
https://medium.com/#hissain.khan/parsing-with-google-gson-library-in-android-kotlin-7920e26f5520
Related
I came across one issue with some of the response we getting is not straight to parse and convert it to POJO. The format of response I am getting is as below
[
"list",
[
{
"#type": "com.exampe.model.ModelName",
"number": 1,
"name": "Test Name",
"url": "/test/url/",
"type": "f"
}
]
]
I want to ignore that "list" and parse a POJO in List of object ModelName. I am using Retrofit and Moshi Convertor but I am not sure how I can achieve this. Is there any way that I can intercept the response before it passed to Moshi Convertor or any different approach that I can go for.
Retrofit Snippet
private fun getRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl(BuildConfig.API_URL)
.addConverterFactory(MoshiConverterFactory.create())
.client(getHTTPClient())
.build()
}
Retrofit offers custom converters (see official documentation),moshi also should offer something similar.
I do not have experience in using moshi, but I have checked documentation and source code - it looks it is possible.
Moshi offers custom adapters which should do things you need. Take a look on PolymorphicJsonAdapterFactory, it has methods fromJson() and toJson() which allows you manually parse json elements in which way you like.
Even more. PolymorphicJsonAdapterFactory looks as an option you need for this.
A JsonAdapter factory for objects that include type information in
the JSON. When decoding JSON. Moshi uses this type information to
determine which class to decode to. When encoding Moshi uses. the
object’s class to determine what type information to include.
Is it possible to convert this :
{
"news": [
{
"nid": 1,
"type": "test1",
},
{
"nid": 2,
"type": "test2",
}
]
}
To this when I receive the result with Retrofit ?
{
"nid": 1,
"type": "test1",
},
{
"nid": 2,
"type": "test2",
}
Actually in my model, I have a NewsList object with a List of News inside (with value inside : nid, type).
And the Retrofit query looks like this :
#GET("test/test.json")
suspend fun getListNews(): Response<Newslist>
Everything is working fine, but now I need to save that data in a database with Room and it will be easier if the Retrofit query was like this :
#GET("test/test.json")
suspend fun getListNews(): Response<List<News>
What is the best way to achieve this ?
Convert Json response to get something like above ?
Keep things like this and Convert the NewsList to be able to be stored in the Room Database ?
The best way is to use RXJava or Coroutine of Kotlin.
In RXJava you can use map operator to transform your response object to list of objects.
Please refer below link to get some idea of using RXJava with retrofit and transforming results:
https://www.journaldev.com/20433/android-rxjava-retrofit
The best way is to have your backend server return the canonical json data.
If this is not possible, you can customize the converterFactor by addConverterFactory method,compatible with this data format in a custom converterFactor.
first, you must to have one layer for data provider to provide for consumer (activity, VM, fragment, etc).
in this layer, you have use case to define data collection from Cloud(Retrofit) or from Local Storage(Room). more info, i have sample here
Yes, you can, using data classes, you just need to create a data class called news with a list of items with "nid" and "type", in that cases I use a plugging of Android Studio Called Kotlin data class File from JSON
I think the better way is to return NewsList object, because it makes you easier to compatible with new feature update, like adding more fields to NewsList object. You can create a new layer for saving your data to room database, and convert the raw data to List for saving it.
I am trying to send an HTTP request and get some data in response. Usually, I just create a class for the response, but now my response contains 5 classes into one field. Generally, the response contains only a few fields(string or integer) but now It contains classes and lists. I am using Retrofit2 in Android Studio.
{
"data": {
“example”:31;
},
" example ": {
“example”:31;
},
" example ": {
“example”:31;
},
}
},
"errors": false,
“example”:31;
} }
Try this solution i think its help you to resolve the query
Retrofit and extracting nested API objects
Try out using Moshi or Gson with Retrofit for parsing (Moshi preferred) - there are many tutorials about it, eg: https://proandroiddev.com/moshi-with-retrofit-in-kotlin-%EF%B8%8F-a69c2621708b
You can also use plugin for Android Studio which makes process of creating classes for GSON / Moshi a lot easier: JsonToKotlinClass (https://plugins.jetbrains.com/plugin/9960-json-to-kotlin-class-jsontokotlinclass-)
BTW: Make sure your example json String is actually correctly created:
https://jsonformatter.curiousconcept.com/
I'm using retrofit to handle rest-api calls.
I have a rest API that returns the following json
"MyObject": {
"43508": {
"field1": 4339,
"field2": "val",
"field3": 15,
"field4": 586.78
},
"1010030": {
"field1": 1339,
"field2": "val212",
"field3": 1,
"field4": 86.78
},...
}
Please notice that the object MyObject contains objects with a name that is actually an id.
For all the other rest APIs I'm using retrofit without problems.
In this case it seems not possible to use the standard approach: defining a class containing the fields expected in the response.
Is there a way to transform this json into a json containing an array of
{
"field1": xxx,
"field2": "yyy",
"field3": www,
"field4": zzz
}
Or is there a better way to deal with this problem without going back to "manually" parsing the json?
Try to use next approach:
public class Response {
Map<String, YourObject> MyObject;
// getter, setter
}
public interface GitHubService {
#GET("some_path")
Call<Response> listMyObjects();
}
All you objects will be parsed to Map. You can get the list of all ids via keySet() method or list all entries with entrySet().
Try putting the annotation, SerializedName(nameOfField) over the variable name.
#SerializedName("13445345")
MyObject object;
Well my idea is quite manual, but it should work. I will not copy and paste another person's answer here, so take a look at this answer to see how to loop through all of the myObject's keys. Then for each of those keys, make a new JSONArray and add key value pair of fieldX-valueX.
This is just a basic idea, since I think you can handle the code yourself, you seem like a guy who knows his way around the simple stuff.
After successfully receiving the first request for information through the Graph API, I attempt to get the next page through the provided public GraphRequest getRequestForPagedResults(PagingDirection direction) method in the com.facebook.GraphResponse class.
However, I keep on getting null as a result on the line JSONObject pagingInfo = graphObject.optJSONObject("paging"); despite the returned JSONObject looking like the JSON code below.
{
"id": "10100476747286781",
"posts": {
"data": [
{
"id": "123123123"
...
}
],
"paging": {
"previous": "https://graph.facebook.com/v2.5/10100476747286781/posts?limit=200&since=1448931408&access_token=CAAM6MhXVsZAYBAN0tW33gMbwnWhs9HtZChlqsGwjgoR2IB9kZCej3pLS8dZCIOSsufYlVlHtJdkOZAHpr0bsPtZAmfj6ZAiXQ9zTXTe9lUghAuXnSQhZBM6YQfRPy26UfXbp4IQe9gKhG50qUZCURtOFAral1NqO8aIoAZCpRZBthp435HCo4uiZA7LqOIK7vxyT6MJ7e3nzcHyOhBDSSaqWYm1L9xUGzmml8Gg6TCZAzUupZCZBwZDZD&__paging_token=enc_AdCrwK4mXgYPS2XHW9Vjgb0ydGnENZCVb8cdyRGdPidfcQAc1573AWMVKR0DNZBzQmxg5ndkZAHfZAvWSpK8UFcG2SBZA&__previous=1",
"next": "https://graph.facebook.com/v2.5/10100476747286781/posts?limit=200&access_token=CAAM6MhXVsZAYBAN0tW33gMbwnWhs9HtZChlqsGwjgoR2IB9kZCej3pLS8dZCIOSsufYlVlHtJdkOZAHpr0bsPtZAmfj6ZAiXQ9zTXTe9lUghAuXnSQhZBM6YQfRPy26UfXbp4IQe9gKhG50qUZCURtOFAral1NqO8aIoAZCpRZBthp435HCo4uiZA7LqOIK7vxyT6MJ7e3nzcHyOhBDSSaqWYm1L9xUGzmml8Gg6TCZAzUupZCZBwZDZD&until=1334148469&__paging_token=enc_AdBEPCJpDZALodXcvmWUJy4rV4mQlFsHFNI8qNlvvVXGYAcZAkB8ZB1i1LRVKZCJND6j71MrINp1FKUDTTgQPZCTEU2t7"
}
}
}
Why doesn't optJSONObject search deeper into the JSON tree?
Is there an interface which I can use to directly use the URL provided in the JSONObject data?
i.e.
"next": "https://graph.facebook.com/v2.5/10100476747286781/posts?limit=200&access_token=CAAM6MhXVsZAYBAN0tW33gMbwnWhs9HtZChlqsGwjgoR2IB9kZCej3pLS8dZCIOSsufYlVlHtJdkOZAHpr0bsPtZAmfj6ZAiXQ9zTXTe9lUghAuXnSQhZBM6YQfRPy26UfXbp4IQe9gKhG50qUZCURtOFAral1NqO8aIoAZCpRZBthp435HCo4uiZA7LqOIK7vxyT6MJ7e3nzcHyOhBDSSaqWYm1L9xUGzmml8Gg6TCZAzUupZCZBwZDZD&until=1334148469&__paging_token=enc_AdBEPCJpDZALodXcvmWUJy4rV4mQlFsHFNI8qNlvvVXGYAcZAkB8ZB1i1LRVKZCJND6j71MrINp1FKUDTTgQPZCTEU2t7"
Personally, from my experience its better to access Facebook using REST API's instead of using their official SDK. It gives me a lot more freedom on how to handle the request-response and skip over any limitations which are part of the SDK.
Additionally, I can use my own networking layer of Volley/OkHttp which makes handling requests and threads much more easier and efficient.