Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Call Type with EventBus

I am using EventBus to notify Activity/Fragment when I get response from the server. Everything works good so far, but problem arises when I consume two network calls in same Fragment or Activity. The problem is the same method onEvent(String response) get calls for both responses from server. The response of call 1 is different from call 2.

I came up with a solution - I added CallType in NetworkReqest but I can't notify the activity/fragment about the network call since post() takes only one parameter.

Here is the relevant code -

public class NetworkRequest {
    EventBus eventBus = EventBus.getDefault();

    public void stringParamRequest(String url, final Map<String, String> params,String callType) {
        StringRequest jsonObjRequest = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        eventBus.post(response);
                    }
                }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d("volley", "Error: " + error.getMessage());
                eventBus.post(error);
            }
        }) {

            @Override
            public String getBodyContentType() {
                return "application/x-www-form-urlencoded; charset=UTF-8";
            }

            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> param = params;
                return param;
            }

        };
        SkillSchoolApplication.get().addToRequestQueue(jsonObjRequest);
    }

    public void stringRequest(String url, String callType) {
        StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                eventBus.post(response);
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        SkillSchoolApplication.get().addToRequestQueue(stringRequest);
    }


}

Method Inside the fragment/activity Here arise the problem when after getting the response from one request i fire another request which is dependent of the respose of the first request

@Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(String response) {
        Log.d(TAG, response);
        boolean isCourseAvaible = false;
        if (!isCourseAvaible) {
            isCourseAvaible = true;
            List<CoursesDTO> coursesDTOs = AppMgr.coursesMgr(response);
            String[] ids = new String[0];
            String id;
            if (coursesDTOs != null) {
                ids = new String[coursesDTOs.size()];
                for (int i = 0; i < coursesDTOs.size(); i++) {
                    ids[i] = coursesDTOs.get(i).getListId();

                }
            }
            id = TextUtils.join(",", ids);
            Map<String, String> map = new HashMap<>();
            map.put("part", "snippet,contentDetails");
            map.put("playlistId", id);
            map.put("key", AppConstants.YOUTUBE_KEY);
            NetworkRequest networkRequest = new NetworkRequest();
            networkRequest.stringParamRequest("some url", map);
        } else {
            Log.d(TAG, response);
        }

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(VolleyError error) {
        Log.d(TAG, error.toString());
        Toast.makeText(getActivity(), "Something went wrong " + error.toString(), Toast.LENGTH_SHORT).show();
    }

How can I differentiate the callType within onEvent(). Some guidance is required. Thanks much.

like image 948
Zeeshan Shabbir Avatar asked Nov 12 '16 07:11

Zeeshan Shabbir


2 Answers

One option is to wrap the two pieces of data you need into a class and pass that to event bus. Leaving off private members, getters/setters and constructors for brevity.

class NetworkResponse() {
   public String callType;
   public String response;
}

When you get a response, allocate a NetworkResponse and populate it with the response and the call type and post that to the event bus.

@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(NetworkResponse networkResponse) {
  if(networkResponse.callType.equals(CALL_1)) {
     // ...
  } else if (networkResponse.callType.equals(CALL_2)) {
     // ...
  }

}
like image 132
iagreen Avatar answered Oct 29 '22 21:10

iagreen


Serialize the String response to a java bean in the onResponse method, and emit the right object to the views. Activities, Fragments and Views have no need to know about serialization, and besides, your app's performance can improve, since you can modify your code to serialize the data in a background thread.

public void stringRequest(String url, String callType) {
        StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                eventBus.post(AppMgr.coursesMgr(response));
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        SkillSchoolApplication.get().addToRequestQueue(stringRequest);
    }

Then your first event subscription will look like this:

@Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(List<CoursesDTO> coursesDTOs) {
        Log.d(TAG, response);
        boolean isCourseAvaible = false;
        if (!isCourseAvaible) {
            isCourseAvaible = true;
            String[] ids = new String[0];
            String id;
            if (coursesDTOs != null) {
                ids = new String[coursesDTOs.size()];
                for (int i = 0; i < coursesDTOs.size(); i++) {
                    ids[i] = coursesDTOs.get(i).getListId();
                }
            }
            id = TextUtils.join(",", ids);
            Map<String, String> map = new HashMap<>();
            map.put("part", "snippet,contentDetails");
            map.put("playlistId", id);
            map.put("key", AppConstants.YOUTUBE_KEY);
            NetworkRequest networkRequest = new NetworkRequest();
            networkRequest.stringParamRequest("some url", map);
        } else {
            Log.d(TAG, response);
        }
    }

and you can have a second, different, String subscription. But since you are going to make the second call anyway, it would be best to execute it directly after getting the right answer from the first one.

public class NetworkRequest {
    EventBus eventBus = EventBus.getDefault();

    public void stringParamRequest(String url, final Map<String, String> params,String callType) {
        StringRequest jsonObjRequest = new StringRequest(Request.Method.POST, url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        eventBus.post(response);
                    }
                }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d("volley", "Error: " + error.getMessage());
                eventBus.post(error);
            }
        }) {

            @Override
            public String getBodyContentType() {
                return "application/x-www-form-urlencoded; charset=UTF-8";
            }

            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> param = params;
                return param;
            }

        };
        SkillSchoolApplication.get().addToRequestQueue(jsonObjRequest);
    }

    public void stringRequest(String url, String callType) {
        StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {  
              List<CoursesDTO> coursesDTOs = AppMgr.coursesMgr(response);
              String[] ids = new String[0];
              String id;
              if (coursesDTOs != null) {
                ids = new String[coursesDTOs.size()];
                for (int i = 0; i < coursesDTOs.size(); i++) {
                    ids[i] = coursesDTOs.get(i).getListId();

                }
              }
              id = TextUtils.join(",", ids);
              Map<String, String> map = new HashMap<>();
              map.put("part", "snippet,contentDetails");
              map.put("playlistId", id);
              map.put("key", AppConstants.YOUTUBE_KEY);
              NetworkRequest networkRequest = new NetworkRequest();
              networkRequest.stringParamRequest("some url", map);                   
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        });
        SkillSchoolApplication.get().addToRequestQueue(stringRequest);
    }
}

Finally, this two lines

  boolean isCourseAvaible = false;
        if (!isCourseAvaible) {

are superfluous, is like having no condition.

like image 39
Fco P. Avatar answered Oct 29 '22 21:10

Fco P.