I have spent hours looking for a solution for getting response message from my loopback API running on node.js. I am trying to get default response message for Users model.

For example, when I want to log in, this is my API POST

@POST("Users/login") Observable<Response> login(@Body User login);

where <Response> is a class which looks like this:

public class Response {
  private String message;
  private String token;

  public String getMessage() {
    return message;
  }

  public String getToken() {
    return token;
  }
}

My RetrofitClient.java for login looks like this:

public static Api getRetrofit(User login) {

        String credentials = login.getEmail() + ":" + login.getPassword();
        String basic = "Basic " + Base64.encodeToString(credentials.getBytes(),Base64.NO_WRAP);
        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();

        httpClient.addInterceptor(chain -> {

            Request original = chain.request();
            Request.Builder builder = original.newBuilder()
                    .addHeader("Authorization", basic)
                    .method(original.method(),original.body());
            return  chain.proceed(builder.build());

        });

And Login.java which handles responses looks like this:

private void loginProcess(User login) {

        mSubscriptions.add(RetrofitClient.getRetrofit(login).login(login)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(this::handleResponse,this::handleError));
    }

    private void handleResponse(Response response) {

        //mProgressBar.setVisibility(View.GONE);
        //Log.d("response", response.getMessage());

        SharedPref.getInstance(this).setToken(response.getToken());
        //SharedPref.getInstance(this).setEmail(response.getMessage());

        emailField.setText(null);
        passwordField.setText(null);

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);

    }

    private void handleError(Throwable error) {

        //mProgressBar.setVisibility(View.GONE);

        if (error instanceof HttpException) {

            Gson gson = new GsonBuilder().create();

            try {

                String errorBody = ((HttpException) error).response().errorBody().string();
                Response response = gson.fromJson(errorBody,Response.class);
                showSnackBarMessage(gson.toJson(error.getMessage()));

            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {

            showSnackBarMessage("Network Error !");
        }
    }

Now, I want to be able to get token when I log in or get error message, for example if API message is: "User doesn't exist", so thats why I have my own Response class also with getToken() method.

Problem is, when error occurs (eg. user doesn't exist), I try to get error message as you can see in Login.java in handleError() but response is always null, probably because I am already in handleError.

I have checked this question, but I couldn't get it to work, because I don't understand how should I use onNext and other methods, or if it even fits for me, since I need to get token from the response.

Just as an example, here is a succesfull response, where id is my token:

{
    "id": "yCZ6K5wWDjtU2WiC1qkmndpOoN3glgH9DWFz0D3rBJVHHI6ebXfxJbsFTTpZNoDf",
    "ttl": 1209600,
    "created": "2019-03-14T22:28:55.697Z",
    "userId": "5c8ad4e140ec9061754f860e"
}

And this is failed login attempt:

{
    "error": {
        "statusCode": 401,
        "name": "Error",
        "message": "login failed",
        "code": "LOGIN_FAILED",
        "stack": "Error: login failed\n    at ..."
    }
}

Related posts

Recent Viewed