How to POST Object Array with Retrofit? - android

I send the data from the postman like this:
{"contacts":[
{
"idContact": "201",
"name": "Joseph",
"lastName": "Herrera",
},
{
"idContact": "202",
"name": "Lizzy",
"lastName": "Martinez",
}
]}
And it works correctly but I tried to POST from retrofit like this:
#FormUrlEncoded
#POST("saveContacts")
fun saveContact(
#HeaderMap headers: Map<String, String>,
#Field("contacts[]") contacts: List<Contact>
): Call<Response>
And this way:
#POST("saveContacts")
fun saveContact(
#HeaderMap headers: Map<String, String>,
#Body contacts: List<Contact>
): Call<Response>
But both ways doesn't work for me. i get a bath response from API:
local.ERROR: Illegal string offset 'idContact' {"userId":1,"exception":"[object] (ErrorException(code: 0): Illegal string offset 'idContact' at
or
local.ERROR: Argument 1 passed to App\Services\ListingService::create() must be of the type array, null given
respectively.
Contacts is a class with the field specified.
I send the Info to retrofit Function like this:
val contacts= listOf(contact1,contact2)
RetrofitClient.instance.saveContact(
headers = headerMap,
contacts = contacts
)
What is the correct way to post this kind of data?

Related

How to get field names as an array from json in Kotlin

I am parsing the below sample json using retrofit in android:
{
"success": true,
"timestamp": 1664080564,
"base": "EUR",
"date": "2022-09-25",
"rates": {
"AED": 3.559105,
"AFN": 86.151217,
"ALL": 116.321643,
"AMD": 404.265711
}
}
As you can see there is no array in this json data, but I want the values of rates as a list or a map so that I can get "AED, AFN, ALL, AMD" as an array too. How can i achieve that using retrofit?
You can define rates as a Map<String, Double> in your data class and Retrofit will automatically parse the rates in form of a Map.
data class MyModel(
val success: Boolean,
val timestamp: Long,
val base: String,
val date: String,
val rates: Map<String, Double>
)
so that I can get "AED, AFN, ALL, AMD" as an array too.
For this you can simply use rates.keys to get all the keys.

Android- Json object come as object or array

I have this json response from the api, and the response can't be change
data class Weather (
val category: String,
val id: String,
val meta: Meta
)
data class Meta (
val id: String,
val name: String,
val details: String
)
Json respose
{
"weather" : {
"category": "articles",
"id": "1",
"meta": {
"id": "1",
"name": "The shortest article. Ever.",
"details": "see"
},
"weather" : {
"category": "articles",
"id": "2",
"meta": []
}
If meta is empty, it come with an array but if not empty, it come with object.
Retrofit throws
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY
the api can't be modify so this has to be fix on client end. How can I solve this
You can not make this possible
meta object must be an object when have value and null when do not have any value, or an array with value when exist and empty when not exist.
meta can not be an array and object in the same time.
this is very bad mistake from who created this response body.
You can use Any type for meta. and put check at your code level like this.
data class Weather (
val category: String,
val id: String,
val meta: Any
)
if(meta is Meta)
parse it to your Meta object
else
parse it to list

Retrofit GET returns empty data list but response has data when executed from Postman

I'm trying to make a simple GET request to our backend server. The request is made successfully and I get status code 200 but one of the attributes (an ArrayList) has no data in the response.
This is particularly strange since the same request returns data in Postman.
I know that the request is going through since I get response code 200.
I don't know what the issue is. Following are the things I have verified are correct.
Base URL is correct
Verified the GET request URL.
Bearer Auth Token is Fine.
Headers (Content-Type & Application) are specified
Retrofit Interface
#Headers("Content-Type: application/json", "Accept: application/json")
#GET("recipe/payment")
fun getMyPurchasedRecipes(
#Header("Authorization") authToken: String
): Call<PurchasedRecipesResponse>
Response Object Data Class
data class PurchasedRecipesResponse(
val code : Int,
val status : String,
#SerializedName("recipes") val recipes : List<Recipes>
)
This is the JSON response in PostMan
{
"code": 200,
"status": "success",
"recipes": [
{
"id": 33,
"title": "Pig tails and Green bananas",
"image_url": "http://api.yardiesfood.com/storage/75/medialibrarykYpREV"
},
{
"id": 32,
"title": "Cheese Omelete",
"image_url": "http://api.yardiesfood.com/storage/68/medialibrarylkjAjm"
}
]
}
In my android app I'm getting the code & status but recipes (from JSON response) returns empty.
Somethings that I have tried
Added headers to the interface #Headers("Content-Type: application/json", "Accept: application/json")
Added #SerializedName to ensure that the JSON to Kotlin class mapping was not the issue.

How to parse nested array insided a json object

So I made an api in laravel and it returns a response like this:
{
"message": "The given data was invalid.",
"errors": {
"email": [
"The email has already been taken."
],
"mobile": [
"The mobile has already been taken."
]
}
}
Can somebody show me how to get the specific values from errors?
You may create model representing your error json and use Gson to parse it. Here is some short example.
data class Errors(
val email: List<String>,
val phone: List<String>
)
data class YourErrorModel(
val message: String,
val errors: Errors
)
fun parseError(response: Response<*>): YourErrorModel? {
val errorBody = response.errorBody()?.string() ?: return null //No error body present
return Gson().fromJson(errorBody, YourErrorModel::class.java)
}
Also don't forget to handle nullable types in your response. And i suggest you to return just string, not array if that is exact error for field.
How about this :
JSONObject errorObject = yourJSONObject.optJSONObject("errors");
if (errorObject != null){
JSONArray emailMsgArray = errorObject.getJSONArray("email");
JSONArray mobileMsgArray = errorObject.getJSONArray("mobile");
String emailMsg= emailMsgArray.getString(0);
String mobileMsg= mobileMsgArray .getString(0);
}

Can't convert json response using gson

When I start request using retrofit 2.0, I'm getting this error com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $
and don't know why, becoause I have a valid json.
I have also seen this kind of error but didn't helped, I don't want to use JsonReader and this kind of stuff
P.S I'm using Gson for converter
[
{
"fullname": "name",
"contact": "blah",
"uid": "001"
},
{
"fullname": "name2",
"contact": "blah2",
"uid": "002"
}
]
this is my call interface method
#FormUrlEncoded
#POST("url")
fun startRequest(#Field("someField") someField: String) : Call<List<MyModelExample>>
and this is my response MyModelExample class
open class MyModelExample : RealmObject() {
#SerializedName("fullname")
var fullName: String? = null
#SerializedName("contact")
var contact: String? = null
#PrimaryKey
#SerializedName("uid")
var uid: String = ""
}

Categories

Resources