Reputation: 49
I'm trying to add "response" json object to my login api using this api response, everything work beside it.
{
"user": {
"id": 1,
"name": "lee",
"lastname": "doe",
"email": "[email protected]",
"email_verified_at": null,
"role_id": 3,
"created_at": null,
"updated_at": null
},
"token": "18|XlZE6z4jyibRoRhVRgGuSJyheyIsz8tyBT7Dz0R9",
"response": {
"error": "false", //return always null on retrofit
"message": "Accesso effettuato" //return always null on retrofit
}
}
Data class that i use for manage data:
Venditore.kt
data class Venditore (
val user: User?=null,
val token: String?=null,
val response:ApiRresponse?=null
)
data class User (
val id: Int?=null,
val name: String?=null,
val password:String?=null,
val lastname:String?=null,
val email: String?=null,
val role_id:Int?=null,
val email_verified_at: Any? = null,
val created_at: Any? = null,
val updated_at: Any? = null
)
data class ApiRresponse(
val error:String?=null,
val message:String?=null
)
if i try to login it works fine, but all the time
response.body()?.response?.message
return null
how should i fix it?
EDIT 1
It can't be null because i'm not fetching data but passing setted information, i thought too that could be back-end issue , but i already tested on Postman and all time return the right format(actually is the JSON that i posted above )
back end
class UserController extends Controller
{
function index(Request $request)
{
$rules = array(
'email' =>'required',
'password' =>'required'
);
$messages = [
'email.required'=> 'email mancante',
'password.required'=> 'password mancante'
];
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)){
$validator = Validator::make($request->all(),$rules,$messages);
if($validator->fails()){
$text_message = $validator->errors()->first();
$response = [
'response'=>[
'error' => 'true',
'message' => $text_message
]
];
return response($response,400);
}
else
{
$response = [
'response'=>[
'error' => 'true',
'message' => 'le credenziali non sono corrette'
]
];
return response($response,401);
}
}
$token = $user->createToken($request->device_name)->plainTextToken;
$APiresponse = [
'error' => 'false',
'message' => 'Accesso effettuato'
];
$response=['user'=> $user,
'token' =>$token,
'response' => $APiresponse
];
return response($response, 201);
}
retrofit call
fun login(){
var email :String = txtEmailUser.text.toString()
var password :String = txtPasswordUser.text.toString()
var deviceName = android.os.Build.MODEL
mServiceV = Common.apiV
Log.d("response", deviceName)
mServiceV.login(email,password,deviceName).enqueue(object : Callback<Venditore> {
override fun onResponse(call: Call<Venditore>, response: Response<Venditore>) {
Log.d("code",response.code().toString())
Log.d("response",response.body().toString())
when(response.code()) {
400->{
Toast.makeText(
this@MainActivity,
response.body()?.response?.message,
Toast.LENGTH_SHORT
).show()
return
}
401 -> {
Toast.makeText(
this@MainActivity,
response.body()?.response?.message,
Toast.LENGTH_SHORT
).show()
return
}
201->{
GlobalVar.Myid = response.body()?.user?.id
GlobalVar.MyT = response.body()?.token
Toast.makeText(this@MainActivity, response.body()?.response?.message, Toast.LENGTH_SHORT).show()
startActivity(Intent(this@MainActivity, MagazzinoActivity::class.java))
}
else->{
if (!response.isSuccessful) {
Toast.makeText(
this@MainActivity,
"Qualcosa è andato storto",
Toast.LENGTH_SHORT
).show()
Log.d("heades", response.code().toString())
return
}
}
}
}
override fun onFailure(call: Call<Venditore>, t: Throwable) {
Toast.makeText(this@MainActivity, t.message!!, Toast.LENGTH_SHORT).show()
}
})
}
UPDATE
response.body()?.response?.message work when login is success i'm sorry i thought it wasn't
QUESTION in case of 400 or 401 code my api response is just
"response": {
"error": "true",
"message": "le credenziali non sono corrette"
}
could be this the problem, like should i still return in this format?
{
"user": {
"id": null,
"name": "null",
"lastname": "null",
"email": "null",
"email_verified_at": null,
"role_id": null,
"created_at": null,
"updated_at": null
},
"token": "null",
"response": {
"error": "false",
"message": "some message"
}
}
Upvotes: 0
Views: 952
Reputation: 49
Finally solved!
Hope this will help someone beside me.
When 4xx code are called response.body() is empty instead of response.errorBody(), so all APIresponse will be there (if you set a custom 4xx code) or default server response.
After understood it i discover also that Retrofit doesn't convert errorBody() like Body() so you should convert by your self.
SOLUTION
val gson = Gson()
val type = object : TypeToken<APIresponse>() {}.type
var errorResponse: APIresponse? = gson.fromJson(response.errorBody()!!.charStream(), type)
//Retriving just message
Toast.makeText(this@MainActivity, errorResponse?.message, Toast.LENGTH_SHORT).show()
Upvotes: 1