1

I am trying to call login API using Retrofit2.

But in onResponse i alwasy get null as response.

Login API endpoint

@FormUrlEncoded 
@POST("/api/login/{mobile}") 
Call<ResObj> userLogin( @Field("phoneNumber") String mobile );

And the API implementation

private void doLogin(final String mobile){
        Call<ResObj> call = userService.login(mobile);
        call.enqueue(new Callback<ResObj>() {
            @Override
            public void onResponse(Call<ResObj> call, Response<ResObj> response) {

                    ResObj resObj = response.body(); // here i am getting null response.body()

                    if(resObj.getMessage().equals("true")){

                        Intent intent = new Intent(Login.this, ListActivity.class);
                        intent.putExtra("mobile", mobile);
                        startActivity(intent);

                    } else{
                        Toast.makeText(Login.this, "Phone Number is incorrect!", Toast.LENGTH_SHORT).show();

                    }
                }

            @Override
            public void onFailure(Call<ResObj> call, Throwable t) {
                Toast.makeText(Login.this, t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });

    }

ResObj class:

public class ResObj {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

I just want to know what causes the error and what are possible solutions.

UPDATE

POSTMAN enter image description here

Jakir Hossain
  • 3,830
  • 1
  • 15
  • 29
Angel
  • 175
  • 1
  • 3
  • 10
  • @KnowNoTrend is NullPointerException the same as Null Object Reference? – Angel Nov 26 '19 at 02:55
  • `ResObj resObj = response.body(); if(resObj.getMessage().equals("true")){` I think so. Also, try debugging it: instead of that, try doing `System.out.println(response.body() == null)`. It will check if it is null, which I think it is. – FailingCoder Nov 26 '19 at 02:59
  • The name of the exception you got was `NullPointerException`. – user207421 Nov 27 '19 at 04:23

1 Answers1

4

You are getting null response in your login API. It may be due to many reasons. You can check your API is working as expected or not using POSTMAN.

And inside your code, you can prevent this type of exception by checking OBJECT is null or not. like the following.

@Override
public void onResponse(Call<ResObj> call, Response<ResObj> response) {

       ResObj resObj = response.body();

       if(resObj != null){ // checking object is not null

          if(resObj.getStatus()){

              Intent intent = new Intent(Login.this, ListActivity.class);
              intent.putExtra("mobile", mobile);
              startActivity(intent);

          } else{
              Toast.makeText(Login.this, "Phone Number is incorrect!", Toast.LENGTH_SHORT).show();
          }
       }else{
          // handle null response here.
       }
}

Update:

According to your Response JSON, Your Model(ResObj) class should be like the following.

public class ResObj 
{
    private String date;

    private String address;

    private String accountName;

    private String contactPerson;

    private String timeOut;

    private String problem;

    private String srNo;

    private String fieldEngineer;

    private String joNo;

    private String irNo;

    private String designation;

    private String email;

    private String timeIn;

    private String productType;

    private boolean status;

    private String contactNo;

    public String getDate ()
    {
        return date;
    }

    public void setDate (String date)
    {
        this.date = date;
    }

    public String getAddress ()
    {
        return address;
    }

    public void setAddress (String address)
    {
        this.address = address;
    }

    public String getAccountName ()
    {
        return accountName;
    }

    public void setAccountName (String accountName)
    {
        this.accountName = accountName;
    }

    public String getContactPerson ()
    {
        return contactPerson;
    }

    public void setContactPerson (String contactPerson)
    {
        this.contactPerson = contactPerson;
    }

    public String getTimeOut ()
    {
        return timeOut;
    }

    public void setTimeOut (String timeOut)
    {
        this.timeOut = timeOut;
    }

    public String getProblem ()
    {
        return problem;
    }

    public void setProblem (String problem)
    {
        this.problem = problem;
    }

    public String getSrNo ()
    {
        return srNo;
    }

    public void setSrNo (String srNo)
    {
        this.srNo = srNo;
    }

    public String getFieldEngineer ()
    {
        return fieldEngineer;
    }

    public void setFieldEngineer (String fieldEngineer)
    {
        this.fieldEngineer = fieldEngineer;
    }

    public String getJoNo ()
    {
        return joNo;
    }

    public void setJoNo (String joNo)
    {
        this.joNo = joNo;
    }

    public String getIrNo ()
    {
        return irNo;
    }

    public void setIrNo (String irNo)
    {
        this.irNo = irNo;
    }

    public String getDesignation ()
    {
        return designation;
    }

    public void setDesignation (String designation)
    {
        this.designation = designation;
    }

    public String getEmail ()
    {
        return email;
    }

    public void setEmail (String email)
    {
        this.email = email;
    }

    public String getTimeIn ()
    {
        return timeIn;
    }

    public void setTimeIn (String timeIn)
    {
        this.timeIn = timeIn;
    }

    public String getProductType ()
    {
        return productType;
    }

    public void setProductType (String productType)
    {
        this.productType = productType;
    }

    public boolean getStatus ()
    {
        return status;
    }

    public void setStatus (boolean status)
    {
        this.status = status;
    }

    public String getContactNo ()
    {
        return contactNo;
    }

    public void setContactNo (String contactNo)
    {
        this.contactNo = contactNo;
    }
}

You are passing parameter as raw data(according to your screen-shot). So your API endpoint would be like below.

@Headers("Content-Type: application/json")
@POST("/api/login") 
Call<ResObj> userLogin(@Body JsonObject jsonObject); 

And call your API like this

private void doLogin(final String mobile){
      try {
           JsonObject paramObject = new JsonObject();
           paramObject.addProperty("mobile", mobile);
        } catch (JSONException e) {
            e.printStackTrace();
        }

      Call<ResObj> call = userService.login(paramObject);
      call.enqueue(new Callback<ResObj>() {

        //your rest of code

      });
}

UPDATE-2:

To send object from one Activity to another using intent you have to make your model class Percelable. like this

// implements Parcelable

public class ResObj implements Parcelable { 
    // ...........your previous code here

    // just simply add the following methods

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(date);
        dest.writeString(address);
        dest.writeString(accountName);
        dest.writeString(contactPerson);
        dest.writeString(timeOut);
        dest.writeString(problem);
        dest.writeString(srNo);
        dest.writeString(fieldEngineer);
        dest.writeString(joNo);
        dest.writeString(irNo);
        dest.writeString(designation);
        dest.writeString(email);
        dest.writeString(timeIn);
        dest.writeString(productType);
        dest.writeByte((byte) (status ? 1 : 0));
        dest.writeString(contactNo);
    }
    public static final Parcelable.Creator<ResObj> CREATOR
            = new Parcelable.Creator<ResObj>() {
        public ResObj createFromParcel(Parcel in) {
            return new ResObj(in);
        }

        public ResObj[] newArray(int size) {
            return new ResObj[size];
        }
    };

    protected ResObj(Parcel in) {
        date = in.readString();
        address = in.readString();
        accountName = in.readString();
        contactPerson = in.readString();
        timeOut = in.readString();
        problem = in.readString();
        srNo = in.readString();
        fieldEngineer = in.readString();
        joNo = in.readString();
        irNo = in.readString();
        designation = in.readString();
        email = in.readString();
        timeIn = in.readString();
        productType = in.readString();
        status = in.readByte() != 0;
        contactNo = in.readString();

    }
}

Now pass your object via intent like the following.

if(resObj != null){

    if(resObj.getStatus()){

        Intent intent = new Intent(Login.this, ListActivity.class);
        intent.putExtra("your_key", resObj); // pass resObj and use same key to get data
        startActivity(intent);

    } else{
        Toast.makeText(Login.this, "Phone Number is incorrect!", Toast.LENGTH_SHORT).show();
    }
}

Get data from your ListActivity like this

@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_second);

     final ResObj yourObject = getIntent().getParcelableExtra("your_key"); // make sure you use same key like data.

     // Now you can use your data like that
     yourEditText.setText(yourObject.getEmail()); 
}
Jakir Hossain
  • 3,830
  • 1
  • 15
  • 29
  • The getMessage should return true if I inputted the correct credentials and false if not. But it is getting null everytime. How do I fix it? – Angel Nov 26 '19 at 09:27
  • `{ "status": true, "srNo": 1, "date": "11/14/2019 12:00:00 AM", "fieldEngineer": "Angel", "accountName": "Forever 21 Megamall", "irNo": 1, "joNo": 1, "address": "Mandaluyong City", "contactPerson": "Jansen Babon", "designation": "", "contactNo": "", "email": "", "timeIn": "00:00:00", "timeOut": "00:00:00", "productType": "Security", "problem": "" }` – Angel Nov 26 '19 at 10:01
  • API is working fine in postman. Here is the response – Angel Nov 26 '19 at 10:01
  • ResObj is already posted. By API endpoint do you mean the base url? – Angel Nov 26 '19 at 10:07
  • I have update my ResObj but it still gets the same error. – Angel Nov 27 '19 at 01:57
  • ` @FormUrlEncoded @POST("/api/login/{mobile}") Call userLogin( @Field("phoneNumber") String mobile ); ` – Angel Nov 27 '19 at 01:58
  • Still gets the same error :( – Angel Nov 27 '19 at 05:01
  • I did. But still gets the same error :( – Angel Nov 27 '19 at 05:08
  • error: incompatible types: String cannot be converted to JsonObject – Angel Nov 27 '19 at 05:13
  • yes. but i get the error of : error: incompatible types: String cannot be converted to JsonObject – Angel Nov 27 '19 at 05:16
  • Do you mean this? ``` try { JsonObject paramObject = new JsonObject(); paramObject.addProperty("mobile", mobile); } catch (JSONException e) { e.printStackTrace(); } ``` – Angel Nov 27 '19 at 05:20
  • Yes. I've already done that – Angel Nov 27 '19 at 05:21
  • @FormUrlEncoded @Headers("Content-Type: application/json") @POST("/api/login") Call userLogin(@Body JsonObject jsonObject); – Angel Nov 27 '19 at 05:24
  • `Call call = userService.login(paramObject);` here i am not using toString(). – Jakir Hossain Nov 27 '19 at 05:26
  • error: exception JSONException is never thrown in body of corresponding try statement – Angel Nov 27 '19 at 05:28
  • @Body parameters cannot be used with form or multi-part encoding. – Angel Nov 27 '19 at 05:32
  • It somehow worked when I input the right credentials but I get the same error when I intentionally input a wrong credential. It still says it is null. – Angel Nov 27 '19 at 05:38
  • it just says that the boolean is false. – Angel Nov 27 '19 at 05:41
  • then you have to change `JSON payload` by asking your backend developer. when invalid credentials found – Jakir Hossain Nov 27 '19 at 05:43
  • What should be the appropriate response? – Angel Nov 27 '19 at 05:45
  • that is the response. the response is: { "status": false, "message": "Mobile No. does not exist." } – Angel Nov 27 '19 at 05:49
  • Nevermind. It is working perfectly now. Thanks! – Angel Nov 27 '19 at 05:50
  • May I know what will I do if I try to fetch multiple data from API? Because here, only mobile is being fetched. – Angel Nov 27 '19 at 09:03
  • I want to display this in the android app: ` { "status": true, "srNo": 1, "date": "11/14/2019 12:00:00 AM", "fieldEngineer": "Angel", "accountName": "Forever 21 Megamall", "irNo": 1, "joNo": 1, "address": "Mandaluyong City", "contactPerson": "Jansen Babon", "designation": "", "contactNo": "", "email": "", "timeIn": "00:00:00", "timeOut": "00:00:00", "productType": "Security", "problem": "" } ` – Angel Nov 27 '19 at 09:10