0

I am a complete noob to Android Studio, Java and Stack Overflow. My app performs a lot of HTTP Post requests using Volley and hence I've made an independent Java class with the code to perform the post request.

public class HTTPReq {
    String[] finalResponse = new String[1];
    public String postRequest(final  HashMap<String,String> params, final Context context) {
        RequestQueue requestQueue = Volley.newRequestQueue(context);
        String url = "https://reqres.in/api/login";
        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                finalResponse[0] = response;
                Toast.makeText(context, "2" + finalResponse[0], Toast.LENGTH_LONG).show();
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                finalResponse[1] = error.getMessage();
                //Toast.makeText(context, "Response Failed", Toast.LENGTH_LONG).show();
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }
        };
        requestQueue.add(stringRequest);
        Toast.makeText(context, "3" + finalResponse[0], Toast.LENGTH_LONG).show();
        return finalResponse[0];
    }
}

What I'm trying to achieve is to get the response of the http request to the function call using return. The function call is as follows:

public void login(String phno, String password,Context context)
{
    HashMap<String,String> credentials = new HashMap<String, String>();
    credentials.put("email","eve.holt@reqres.in");
    credentials.put("password","cityslicka");
    HTTPReq httpReq = new HTTPReq();
    String response = httpReq.postRequest(credentials,context);
    Toast.makeText(context, "1" + response, Toast.LENGTH_LONG).show();
}

I hope it's clear what I'm trying to achieve. Please help me with this.

  • It looks like your method should **return** `response` so it's type should be `String` (not `void`). – PM 77-1 May 27 '20 at 17:37
  • @PM77-1 do you mean the public void onResponse(String response) method? When I set it's type to String I get the following error: ``` error: .HTTPReq$1> is not abstract and does not override abstract method onResponse(String) in Listener StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new Response.Listener() { ``` – Somesh S S May 27 '20 at 17:57
  • I meant `login` method. May be I misunderstood your design. – PM 77-1 May 27 '20 at 18:43
  • I don't think login is meant to return anything. I want the class HTTPReq to return the response to the login function. – Somesh S S May 27 '20 at 19:36
  • Your class does not have ***state***. – PM 77-1 May 27 '20 at 19:51
  • Yes please explain more. I new to this so please explain in more detail and tell me exactly what to do and where. – Somesh S S May 27 '20 at 20:11
  • https://docs.oracle.com/javase/tutorial/java/concepts/object.html – PM 77-1 May 27 '20 at 20:34

1 Answers1

1

your con use feature interface

   public class HTTPReq {
    public void postRequest(final HashMap<String, String> params, final Context context, final ResponseCallBack callBack) {
        RequestQueue requestQueue = Volley.newRequestQueue(context);
        String url = "https://reqres.in/api/login";
        StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {

            @Override
            public void onResponse(String response) {
                callBack.onResponse(response);
                Toast.makeText(context, response, Toast.LENGTH_LONG).show();

            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                callBack.onError(error);
                Toast.makeText(context, "Response Failed", Toast.LENGTH_LONG).show();
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                return params;
            }

            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                Map<String, String> params = new HashMap<String, String>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }
        };

        requestQueue.add(stringRequest);

    }
}

calss interface :

import com.android.volley.VolleyError;

public interface ResponseCallBack<T> {
        public void onResponse(T response);

        public void onError(VolleyError error_response);


}

MainActivity:

public class MainActivity extends AppCompatActivity implements ResponseCallBack {

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

    HTTPReq httpReq = new HTTPReq();
    HashMap<String, String> credentials = new HashMap<String, String>();
    credentials.put("email", "eve.holt@reqres.in");
    credentials.put("password", "cityslicka");

    httpReq.postRequest(credentials, this, this);

}

@Override
public void onResponse(Object response) {
    Log.e("TAG", "onResponse: " + response);
}

@Override
public void onError(VolleyError error_response) {

    Log.e("TAG", "onError: " + error_response);
}
Javad Dehban
  • 1,282
  • 3
  • 11
  • 24
  • I don't think you've understood my question well. I want the postResponse function to return response to the function call. – Somesh S S May 28 '20 at 18:12
  • my answer edit. I think this is the code you wanted. – Javad Dehban May 28 '20 at 18:20
  • Thanks @Javad the function gives no errors. But it keeps returning an empty array. I'm still not getting the response which my url provides. – Somesh S S May 28 '20 at 20:47
  • can you send your code and url to my email address? maybe i can help you – Javad Dehban May 28 '20 at 20:50
  • I added a few toasts for debugging. 1 after the function call inside login method (Toast number 1). 1 inside the OnResponse method(Toast number 2) and 1 just before the last return finalResponse[0]; (Toast number 3). When I run the code and perform login, the toasts appear in the order: 3 1 2. And when the 2 toast appears the correct response from the server is shown. From this I can deduce that the return finalResponse[0]; is happening even before the function gets the response from my server. How can I make my system wait for response before continuing? – Somesh S S May 28 '20 at 21:04
  • Please email me the server address so I can debug with break point – Javad Dehban May 28 '20 at 21:11
  • You can perform the post on this link: https://reqres.in/api/login Use the data as: credentials.put("email","eve.holt@reqres.in"); credentials.put("password","cityslicka"); in the login method. I have edited the original question to match with the current progress. – Somesh S S May 28 '20 at 21:51
  • I think the problem here is since volley is asynchronous, it will do the requests in the background. That's how it is meant to work. So making it work as synchronous job is what we are looking for. This link might help you. I don't understand anything there (I'm new to this). Link: https://stackoverflow.com/questions/16904741/can-i-do-a-synchronous-request-with-volley – Somesh S S May 29 '20 at 09:53
  • I solved our problem. You must use the interface. Because volley uses a thread apart from thread android. more information : https://developer.android.com/training/volley/request-custom.html https://developer.android.com/reference/java/lang/Thread – Javad Dehban May 29 '20 at 10:43
  • Your solution has given me a way to get the result back to the same Java class from where the Request was called but this is not exactly what I have asked for in my question. I wanted the response to be returned to the response variable in the function call. However, I think I can cook something up with this solution and make things work. Thankyou! – Somesh S S May 30 '20 at 07:12