using retrofit enqueue calls - android

I'm new to android. I'm trying to make a call to a rest service with jwt.
Is there a better way to make these 2 calls?
Looks poorly written because the call to the service is attached to the jwt call and unless the jwt token is expired it shouldn't call that service every time, right?
Thanks in advance for your feedback
final GetDataService service = RetrofitClientInstance.getRetrofitInstance().create(GetDataService.class);
Call<Void> tokenCall = service.geToken(new AccountCredentials("admin", "password"));
tokenCall.enqueue(new Callback<Void>() {
#Override
public void onResponse(Call<Void> call, Response<Void> response) {
progressDialog.dismiss();
token = response.headers().get("Authorization");
Call<List<Event>> eventCall = service.getAllEvents(token);
eventCall.enqueue(new Callback<List<Event>>() {
#Override
public void onResponse(Call<List<Event>> call, Response<List<Event>> response) {
progressDialog.dismiss();
generateDataList(response.body());
}
#Override
public void onFailure(Call<List<Event>> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onFailure(Call<Void> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});

it's a good solution. but you can enhance the design of code by writing the second call in a new method and just call the method.
the better solution is to using the RXJAVA see
https://medium.com/#adinugroho/chaining-multiple-retrofit-call-using-rxjava-177b64c8103e
https://www.captechconsulting.com/blogs/a-mvp-approach-to-lifecycle-safe-requests-with-retrofit-20-and-rxjava
https://medium.com/#mtrax/rxandroid-2-with-retrofit-2-and-gson-3f08d4c2627d

Related

how to save Tokens in retofit in saveprefrence and delete on logout for offline auth android

i am new to retrofit i want to be able to save token that would be pesisted when ever a user opens the app and deleted when the user logoutof the apps like what firebase does Thanks in advance
Do this for your retrofit callback.....
call.enqueue(new Callback<AllResponseData>() {
#Override
public void onResponse(Call<AllResponseData> call, Response<AllResponseData> response) {
pDialog.dismiss();
if (response.isSuccessful()) {
ResultBody result = (ResultBody) response.body();
if (result.isSuccess()) {
PreferenceManager.getDefaultSharedPreferences(context).edit().putString("token", result.getToken()).commit();
// other stuff over here
} else
Log.d("sushildlh",result.getMessage());
} else
Toast.makeText(context, response.message(), Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<AllResponseData> call, Throwable t) {
pDialog.dismiss();
}
});
do this on logout button.....
PreferenceManager.getDefaultSharedPreferences(context).edit().putString("token", "").commit()
// other stuff over here

How can I use the Retrofit response outside the OnResponse function?

I want to get the retrofit response list and use it outside the OnResponse function, but went I try to do it I'm always getting a null object.
Here is my source code
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<ActivitiesResponse> call = apiService.getUserActivities(id);
call.enqueue(new Callback<ActivitiesResponse>() {
// If success
#Override
public void onResponse(Call<ActivitiesResponse>call, Response<ActivitiesResponse> response) {
list = response.body().getActivities();// I'm getting a not null response
}
// If failed
#Override
public void onFailure(Call<ActivitiesResponse>call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
//When I try to use the list here I'm getting a null object
Requests are async, so when you try to return a value, the request is likely not done yet so you cannot use it outside of the request. If you want to return values from the request use callback interfaces.
Change your code to a method and pass a callback parameter
Example
public void doRequest(final ApiCallback callback) {
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
Call<ActivitiesResponse> call = apiService.getUserActivities(id);
call.enqueue(new Callback<ActivitiesResponse>() {
// If success
#Override
public void onResponse(Call<ActivitiesResponse>call, Response<ActivitiesResponse> response) {
list = response.body().getActivities();
callback.onSuccess(list); // pass the list
}
// If failed
#Override
public void onFailure(Call<ActivitiesResponse>call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
}
public interface ApiCallback{
void onSuccess(ArrayList<YOURTYPE> result);
}
Example usage in onResume(), basically you can do this anywhere you want:
public void onResume(){
super.onResume();
doRequest(new ApiCallback(){
#Override
public void onSuccess(ArrayList<YOURTYPE> result){
//do stuff here with the list from the request
}
});
}
Let me know if this fits your needs
Because onResponse() runs asynchronously. You can not get its value like that.
You should call the method which uses list value inside onResponse().
For example.
call.enqueue(new Callback<ActivitiesResponse>() {
// If success
#Override
public void onResponse(Call<ActivitiesResponse>call, Response<ActivitiesResponse> response) {
list = response.body().getActivities();// I'm getting a not null response
yourMethod();
}
// If failed
#Override
public void onFailure(Call<ActivitiesResponse>call, Throwable t) {
// Log error here since request failed
Log.e(TAG, t.toString());
}
});
private void yourMethod() {
// list is used somewhere here
}

Null context in onResponse callback method retrofit android

I have a DialogFragment. When i click the OK button, i execute a retrofit call to my api like this
#Override
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
int code = response.code();
if (code == 200) {
LoginResponse lr = response.body();
if (lr.getError()) {
Utils.showToast(getActivity(), "Error! Los datos son incorrectos.");
} else {
startActivity(new Intent(getActivity(), ConfigGeneralActivity.class));
}
} else {
Toast.makeText(getActivity(), "Error: " + String.valueOf(code), Toast.LENGTH_LONG).show();
}
}
at this part of the code, getActivity() is null.
Another option is to pass the context from the oncreatedialog to this callback, but when i do this, i got the error that says activity is not attached to fragment.
I know i can implement Otto but it's too complex for what i want to do. I just want to start a new activity from a retrofit callback inside a DialogFragment.
Any ideas? Thanks!
You need to runOnUiThread to get the Context inside OnResponse Callback
Like:
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()) {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
//your code
}
});
}
}

Retrofit cancel request

I'm using Retrofit 2.0. To get some data from RESTFull services I use procedures like this:
public Call downloadUser() {
// Create RetrofitService
Call<User> call = service.getUser();
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Response<User> response, Retrofit retrofit) {
// Do some operations with User obj if response.isSuccess()
}
#Override
public void onFailure(Throwable t) {
// Failure
}
});
return call;
}
In some cases, I need to cancel my request. I use call.cancel(), but even if I call this procedure Callback.onResponse(...) or Callback.onFailure(...) triggered anyway, so using Call.cancel() doesn't cancel my request and it keeps on going until failure or response.
To know if a call was canceled or if it was truly successful you'll need to two a few things.
First it looks like the version of Retrofit2 you are using needs to be updated
Second you can check if a call was canceled based on the code below. Note that this will deal with cancels from the Call<> or the Dispatcher.class in OKHttp3
#Override
public void onResponse(Response<User> response, Response response) {
if(response != null && response.isSuccessful()) {
//Do Stuff with the response
}
}
#Override
public void onFailure(Call<User> user, Throwable t) {
if(user.isCanceled() || "Canceled".equals(t.getMessage())) {
//Call was canceled
} else {
//Call failed
}
}

How is error handling done in Retrofit 2 ? I can not find the RetrofitError class that most of the solutions suggest?

I want to implement a error handling mechanism using Retorfit 2.
The solutions that are available are using RetrofitError class which I can't find in the current repo.
If you are making synchronous request, you define your request method in the interface as Call<List<Car>>.
Once you execute the request you receive response and deserialized data wrapped in Response<T> as Response<List<Car>>. This wrapped gives you access to headers, http codes and raw response body.
You can access error body as:
Call<List<Car>> carsCall = carInterface.loadCars();
try {
Response<List<Car>> carsResponse = carsCall.execute();
} catch (IOException e) {
e.printStackTrace();
//network Exception is throw here
}
if(carsResponse != null && !carsResponse.isSuccess() && carsReponse.errorBody() != null){
// handle carsResponse.errorBody()
}
For async calls, you receive Throwable, if I/O exception is thrown during the network call:
Call<List<Car>> call = service.loadCars();
call.enqueue(new Callback<List<Car>>() {
#Override
public void onResponse(Response<List<Car>> response) {
// Get result from response.body(), headers, status codes, etc
}
#Override
public void onFailure(Throwable t) {
//handle error
}
});
Call<List<data>> call = MyService.loadData();
call.enqueue(new Callback<List<data>>() {
#Override
public void onResponse(Call<List<data>> call, Response<List<data>> response) {
if (response.isSuccessful()) {
//Response success. Handle data here
}
else{
//For getting error message
Log.d("Error message",response.message());
//For getting error code. Code is integer value like 200,404 etc
Log.d("Error code",String.valueOf(response.code()));
}
}
#Override
public void onFailure(Call<List<data>> call, Throwable t) {
if (t instanceof IOException){
//Add your code for displaying no network connection error
}
});
The simple method:
int code = response.raw().code();
String message = response.raw().message();

Categories

Resources