I want to run changesHasBeenSaved if saveChanges function gives me true value.
How can I get boolean or string or integer, any value, when Retrofit finish?
Is it possible?
I need a function similar this:
public boolean saveChanges()
{
Boolean output = false;
RequestAPI requestAPI = Requests.getRetrofit();
Call<Object> jsonObjectCall = requestAPI.readAllCategoeies();
jsonObjectCall.enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
if(response.body() != null) {
output = true;
}
}
#Override
public void onFailure(Call<Object> call, Throwable t) {
call.cancel();
}
});
return output;
}
You should change method return type boolean to void as retrofit work asynchronous.
You should pass the listener/callback to get the status in callback.
First create callback interface like below
public interface ApiCallback {
void onResponse(boolean success);
}
Here how saveChanges will look like
public void saveChanges(final ApiCallback callback)
{
RequestAPI requestAPI = Requests.getRetrofit();
Call<Object> jsonObjectCall = requestAPI.readAllCategoeies();
jsonObjectCall.enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
callback.onResponse(response.body() != null);
}
#Override
public void onFailure(Call<Object> call, Throwable t) {
call.cancel();
callback.onResponse(false);
}
});
}
Then you need to call saveChanges method like below
saveChanges(new ApiCallback () {
public void onResponse(boolean success){
if(success){
// do something
} else{
// do something
}
}
});
jsonObjectCall.enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
//when the response is successful
if(response.isSuccessful()) {
output = true;
// display response as string
Log.i(TAG, "post submitted to API." + response.body().toString());
//Object user1 = response.body(); maps response to the modal class
}
}
#Override
public void onFailure(Call<Object> call, Throwable t) {
call.cancel();
}
})
Change you call back to like the above , included comments for clearity about usage .
Hope this helps.
Related
Activity
#Override
protected void onResume() {
super.onResume();
getCartList();
}
private void getCartList() {
showProgressDialog();
Call<List<CartList>> call = api.getCartList(1);
call.enqueue(new Callback<List<CartList>>() {
#Override
public void onResponse(Call<List<CartList>> call, Response<List<CartList>> response) {
cartLists = response.body();
if (cartLists.size() == 0) {
tvCartEmpty.setVisibility(View.VISIBLE);
progressDialog.cancel();
} else {
addToCartAdapter.setData(cartLists);
productList.setAdapter(addToCartAdapter);
progressDialog.cancel();
}
}
#Override
public void onFailure(Call<List<CartList>> call, Throwable t) {
Toast.makeText(AddToCartActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void deleteItemID(int id) {
Call<CartList> deleteCall = api.deleteCartItem(id);
deleteCall.enqueue(new Callback<CartList>() {
#Override
public void onResponse(Call<CartList> call, Response<CartList> response) {
Log.d(TAG, "deleteItem by id" + response.code());
onResume();
}
#Override
public void onFailure(Call<CartList> call, Throwable t) {
Log.d(TAG, t.getMessage());
}
});
}
i mean last is deleting but not updating on the spot even though i called onresume in delete item method.
i have to open that activity again to see updted result
i hope i will get my query solved soon!
thanks
if you want i will upload inteface and adapter code. which i do not think necessary here.
Solution
just had to add this in response class
public void onResponse(Call<List<CartList>> call, Response<List<CartList>> response) {
cartLists = response.body();
if (cartLists.size() == 0) {
tvCartEmpty.setVisibility(View.VISIBLE);
tvCartItems.setText("0 items");
addToCartAdapter.setData(cartLists);
progressDialog.cancel();
} else {
addToCartAdapter.setData(cartLists);
productList.setAdapter(addToCartAdapter);
tvCartItems.setText(cartLists.size() + " Items");
progressDialog.cancel();
}
}
you don't need to call onResume() again.
instead of that you should use the following snippet:
cartLists.removeAt(id);
addToCartAdapter.notifyDataSetChanged();
your deleteItem function would look like below code:
#Override
public void deleteItemID(int id) {
Call<CartList> deleteCall = api.deleteCartItem(id);
deleteCall.enqueue(new Callback<CartList>() {
#Override
public void onResponse(Call<CartList> call, Response<CartList> response) {
Log.d(TAG, "deleteItem by id" + response.code());
cartLists.removeAt(id);
addToCartAdapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<CartList> call, Throwable t) {
Log.d(TAG, t.getMessage());
}
});
I am working with Retrofit (JSON Parsing Android) and I am new with this I am so confused to set the response with the Base Adapter.
This is my Example Class
public class Example {
#SerializedName("Totalrecord")
#Expose
private List<Totalrecord> totalrecord = null;
#SerializedName("Table1")
#Expose
private List<Table1> table1 = null;
#SerializedName("Table2")
#Expose
private List<Table2> table2 = null;
public List<Totalrecord> getTotalrecord() {
return totalrecord;
}
public void setTotalrecord(List<Totalrecord> totalrecord) {
this.totalrecord = totalrecord;
}
public List<Table1> getTable1() {
return table1;
}
public void setTable1(List<Table1> table1) {
this.table1 = table1;
}
public List<Table2> getTable2() {
return table2;
}
public void setTable2(List<Table2> table2) {
this.table2 = table2;
}
}
Here I am trying to retrieve Response in ArrayList so that I can set it to Adapter
ApiService api = RetroClient.getApiService();
Call<Example> call = api.getMyJson(38, 109);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
dialog.dismiss();
if (response.isSuccessful()) {
// Response_list = response.body().get...
adapter_view = new Adapter_view(Response_list, MainActivity.this);
listView.setAdapter(adapter_view);
}
}
#Override
public void onFailure(Call<Example> call, Throwable t) {
dialog.dismiss();
System.out.println("failed");
}
});
But I am confused to set The type of ArrayList and also Type of Callback<> so that I can get the response properly and set ArrayList to the Adapter.
try following if you want to set List<Totalrecord> in your adapter.
ApiService api = RetroClient.getApiService();
Call<Example> call = api.getMyJson(38, 109);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
dialog.dismiss();
if (response.isSuccessful()) {
Response_list.clear();
Response_list.addAll(call.getTotalrecord());
adapter_view = new Adapter_view(Response_list, MainActivity.this);
listView.setAdapter(adapter_view);
}
}
#Override
public void onFailure(Call<Example> call, Throwable t) {
dialog.dismiss();
System.out.println("failed");
}
});
List<Table1> mList=new ArrayList();
ApiService api = RetroClient.getApiService();
Call<Example> call = api.getMyJson(38, 109);
call.enqueue(new Callback<Example>() {
#Override
public void onResponse(Call<Example> call, Response<Example> response) {
dialog.dismiss();
if (response.body.isSuccessful()) {
mList=response.body.getTable1();
adapter_view = new Adapter_view(mList,MainActivity.this);
listView.setAdapter(adapter_view);
}
}
#Override
public void onFailure(Call<Example> call, Throwable t) {
dialog.dismiss();
System.out.println("failed");
}
});
com.squareup.retrofit2:retrofit:2.3.0
My steps:
Start async request: getCompaniesList()
Wait success response
Start another async request: getCatalogsList()
Wait success response
Do some another code
Here snippet in my activity:
RestClient restClient = RestClientFactory.getRestClient();
Call<List<Company>> companyList = restClient.getCompaniesList(filters);
companyList.enqueue(new Callback<List<Company>>() {
#Override
public void onResponse(Call<List<Company>> call, Response<List<Company>> response) {
if (response.isSuccessful()) {
RestClient restClient = RestClientFactory.getRestClient();
Call<List<Catalog>> catalogList = restClient.getCatalogsList(filters);
catalogList.enqueue(new Callback<List<Catalog>>() {
#Override
public void onResponse(Call<List<Catalog>> call, Response<List<Catalog>> response) {
if (response.isSuccessful()) {
// HERE SOME NEED CODE!!!
}
}
#Override
public void onFailure(Call<List<Catalog>> call, Throwable throwable) {
}
});
}
}
#Override
public void onFailure(Call<List<Company>> call, Throwable throwable) {
}
});
I think this structure is not very nice. Тoo many nested items. As result code is more complicated.
Question: Has any alternative to this structure?
You can either take time to learn Rx RXjava2
or you can split up your code like this
RestClient restClient = RestClientFactory.getRestClient();
Call<List<Company>> companyList = restClient.getCompaniesList(filters);
companyList.enqueue(getCompanyListCallback());
private Callback<List<Company>> getCompanyListCallback() {
return new Callback<List<Company>>() {
#Override
public void onResponse(Call<List<Company>> call, Response<List<Company>> response) {
if (response.isSuccessful()) {
RestClient restClient = RestClientFactory.getRestClient();
Call<List<Catalog>> catalogList = restClient.getCatalogsList(filters);
catalogList.enqueue(getCatalogsListCallback());
}
}
#Override
public void onFailure(Call<List<Company>> call, Throwable throwable) {
}
};
}
private Callback<List<Catalog>> getCatalogsListCallback() {
return new Callback<List<Catalog>>() {
#Override
public void onResponse(Call<List<Catalog>> call, Response<List<Catalog>> response) {
if (response.isSuccessful()) {
// HERE SOME NEED CODE!!!
}
}
#Override
public void onFailure(Call<List<Catalog>> call, Throwable throwable) {
}
};
}
I have this project and wish to get all names from table like "1" is the first name how code this for all names
public void capturarPersonagens(View view) {
//-- Retrofit
callPersonagem = service.getPersonagem("1");
callPersonagem.enqueue(new Callback<Personagem>() {
#Override
public void onResponse(Call<Personagem> call, Response<Personagem> response) {
if (response.isSuccessful()) {
if (!call.isCanceled()) {
Log.i("Personagem",response.body().getName());
}
}
}
}
}
Best Regards
Pedro Duarte
You are missing a new method in your Service interface:
The api endpoint people/?format=json depends on the actual implementation of your webservice.
public interface Service {
#GET("people/{id}/?format=json")
Call<Personagem> getPersonagem(#Path("id") String alacazam);
#GET("people/?format=json")
Call<ArrayList<Personagem>> getPersonagens();
}
Then, you may consume it the same way you did with getPersonagem:
public void capturarPersonagens(View view) {
//-- Retrofit
callPersonagens = service.getPersonagens();
callPersonagens.enqueue(new Callback<ArrayList<Personagem>>() {
#Override
public void onResponse(Call<ArrayList<Personagem>> call, Response<ArrayList<Personagem>> response) {
if (response.isSuccessful()) {
if (!call.isCanceled()) {
for(Personagem p:response.body()){
Log.i("Personagem",p.getName());
}
}
}
}
#Override
public void onFailure(Call<ArrayList<Personagem>> call, Throwable t) {
Log.e("SW", "" + t.getMessage());
}
});
}
I want to do an unit test that verifies if function1() or function2() were called. I haven't work with callbacks before, can you give me any idea about how to do it?
public void sendData(HttpService service, Document userData) {
Call<String> call = service.updateDocument(getId(), userData);
call.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
function1(response.code());
}
#Override
public void onFailure(Call<String> call, Throwable t) {
function2();
}
});
}
I couldn't try, but it should work. Maybe you have to fix generic type
casting errors like mock(Call.class);.
#Test
public void should_test_on_response(){
Call<String> onResponseCall = mock(Call.class);
doAnswer(invocation -> {
Response response = null;
invocation.getArgumentAt(0, Callback.class).onResponse(onResponseCall, response);
return null;
}).when(onResponseCall).enqueue(any(Callback.class));
sendData(....);
// verify function1
}
#Test
public void should_test_on_failure(){
Call<String> onResponseCall = mock(Call.class);
doAnswer(invocation -> {
Exception ex = new RuntimeException();
invocation.getArgumentAt(0, Callback.class).onFailure(onResponseCall, ex);
return null;
}).when(onResponseCall).enqueue(any(Callback.class));
sendData(....);
// verify function2
}