I am trying to create a new ArrayList instance and initialize it to an arraylist returned by a function. The things I have tried so far do not work.
This is my function which is supposed to return an ArrayList of type . I have tested it and it works perfectly, the contents are read successfully and are stored in the temporary ArrayList created within the function. After filling this ArrayList the function will return it.
public ArrayList<User> fetchAllUsers() {
final ArrayList<User> allUsers = new ArrayList<>();
RequestQueue requestQueue = Volley.newRequestQueue(this);
JsonArrayRequest arrayRequest = new JsonArrayRequest(
Request.Method.GET,
"http://ecoproduce.eu/api/User",
null,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.e("Rest response", response.toString());
Gson gson = new Gson();
User user = new User();
for (int i = 0; i < response.length(); i++) {
try {
user = gson.fromJson(response.getJSONObject(i).toString(), User.class);
} catch (JSONException e) {
e.printStackTrace();
}
allUsers.add(user);
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Error response", error.toString());
}
}
);
requestQueue.add(arrayRequest);
return allUsers;
}
The problem I face is when I try to declare a new arrayList instance and I try to fill it with the ArrayList returned from the function.
I have tried doing this in the following ways:
Initialize the newly created instance through the constructor:
ArrayList<User> allUsers = new ArrayList<User>(fetchAllUsers());
Initialize the newly created instace of ArrayList through the addAll() function
ArrayList<User> allUsers = new ArrayList<User>();
allUsers.addAll(fetchAllUsers());
Both of these attempts have left me with an empty ArrayList, how can I solve this?
SOLUTION:
Implemented an interface
public interface VolleyCallBack {
ArrayList<User> onSuccess();
}
Changes to the getAllUsers function
public ArrayList<User> getAllUsers(final String email, final VolleyCallBack callBack) {
requestQueue = Volley.newRequestQueue(this);
JsonArrayRequest arrayRequest = new JsonArrayRequest(
Request.Method.GET,
"http://ecoproduce.eu/api/User",
null,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.e("Rest response", response.toString());
Gson gson = new Gson();
User user = new User();
for (int i = 0; i < response.length(); i++) {
try {
user = gson.fromJson(response.getJSONObject(i).toString(), User.class);
} catch (JSONException e) {
e.printStackTrace();
}
allUsers.add(user);
}
/*for (int i = 0; i < allUsers.size(); i++) {
if (allUsers.get(i).getEmail().compareTo(email) == 0) {
checkSucesfull = true;
}
}*/
callBack.onSuccess();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Error response", error.toString());
}
}
);
requestQueue.add(arrayRequest);
return allUsers;
}
How I call the function now
allUsers = getAllUsers(email, new VolleyCallBack() {
@Override
public ArrayList<User> onSuccess() {
return allUsers;
}
});
And the allUsers ArrayList is made global (which is probably not the best solution).
I am still open to improvements on this.
What I am getting is you are making an asynchronous call to get the list items. which will come sometime later but the initialization will happen as soon as the function gets called. Your ArrayList is in synchronous and the method fetchAllUsers() calls for an API to in background thread to fill the items in ArrayList but returns an empty list instantly that's why you are getting empty list.
So in actual you can't initialize some ArrayList which depends on the background thread. you can use callbacks to get the data later but not instantly i hope you are getting my point.
Now what to do: Depends on what you are trying to achieve but just return nothing from fetchAllUsers and on callback of api call do whatever you want to do
public void fetchAllUsers() {
final ArrayList<User> allUsers = new ArrayList<>();
RequestQueue requestQueue = Volley.newRequestQueue(this);
JsonArrayRequest arrayRequest = new JsonArrayRequest(
Request.Method.GET,
"http://ecoproduce.eu/api/User",
null,
new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.e("Rest response", response.toString());
Gson gson = new Gson();
User user = new User();
for (int i = 0; i < response.length(); i++) {
try {
user = gson.fromJson(response.getJSONObject(i).toString(), User.class);
} catch (JSONException e) {
e.printStackTrace();
}
allUsers.add(user);
}
//here your list items are ready to be used, so call some function to consume it
//TODO call to further function
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Error response", error.toString());
}
}
);
requestQueue.add(arrayRequest);
}