How to set timeout for Api call using retrofit in flutter? - flutter

Where we can set timeout in below code?
As you can see I am using retrofit for api call.
Dio Object
class DioObject{
static Dio getDio(){
debugPrint("Bearer:- ${PrefHelper().pref?.getString(PrefHelper.AUTHORIZATION)}");
final dio = Dio(); // Provide a dio instance
dio.options.headers["Authorization"] =
"Bearer ${PrefHelper().pref?.getString(PrefHelper.AUTHORIZATION)}"; // config your dio headers globally
dio.options.headers["Content-Type"] =
"application/json;charset=UTF-8"; // config your dio headers globally
return dio;
}
}
Api call
final client = RestClient(DioObject.getDio());
var response = await client.xyz();
Rest API
#RestApi(baseUrl: "*****/api")
abstract class RestClient {
factory RestClient(Dio dio, {String baseUrl}) = _RestClient;
#GET("/UserAccessPoints/")
Future<CommonResponse> xyz();
}

You can do it the same way you added your custom headers, or doing it all at once with a BaseOptions object
final dio = Dio();
//Dio Options
dio.options = BaseOptions(
contentType: 'application/json',
connectTimeout: 4000,
sendTimeout: 4000,
receiveTimeout: 10000,
headers : ...
);

Related

XMLHttpRequest on Flutter Dio Package with Spring Boot server

I'm trying to make a request to my server with a Flutter Web Application using Dio package. It's returning the XMLHttpRequest error but the server is receveing the request normally.
I'm aware that with disable security command the problem vanish, but I need a solution for production as weel.
Dio code:
import 'package:dio/dio.dart';
import '../interceptor/api_interceptor.dart';
class DioApi {
static String backendUrl = "http://localhost:8080/api/";
static Dio _getDio({Map<String, dynamic>? headers}) {
BaseOptions baseOptions = BaseOptions(
baseUrl: backendUrl,
receiveDataWhenStatusError: true,
connectTimeout: 60 * 1000,
receiveTimeout: 60 * 1000,
);
if (headers != null) {
baseOptions.headers.addAll(headers);
}
Dio dio = Dio(baseOptions);
dio.interceptors.add(ApiInterceptor());
return dio;
}
static Future<Response> get(
String url,
{Map<String, dynamic>? headers, Map<String, dynamic>? queryParameters}) async {
return _getDio(headers: headers).get(url, queryParameters: queryParameters);
}
static Future<Response> post(
String url,
dynamic data,
{Map<String, dynamic>? headers, Map<String, dynamic>? queryParameters}) async {
return _getDio(headers: headers).post(url, data: data, queryParameters: queryParameters);
}
}
--disable-web-security can't help me and CORS on server side seems fine.

How to update a get it instance in flutter?

I am using the getIt package to create instances in my application.
instance.registerLazySingleton<DioFactory>(() => DioFactory(instance()));
// app service client
final dio = await instance<DioFactory>().getDio();
instance.registerLazySingleton<AppServiceClient>(() => AppServiceClient(dio));
Above code is for initialising the instances.
The getDio() function:
Future<Dio> getDio() async {
Dio dio = Dio();
int _timeOut = 60 * 1000; // 1 min
String language = await _appPreferences.getAppLanguage();
Map<String, String> headers = {
CONTENT_TYPE: APPLICATION_JSON,
ACCEPT: APPLICATION_JSON,
AUTHORIZATION: Constants.token,
DEFAULT_LANGUAGE: language
};
dio.options = BaseOptions(
baseUrl: Constants.baseUrl,
connectTimeout: _timeOut,
receiveTimeout: _timeOut,
headers: headers);
if (kReleaseMode) {
} else {
dio.interceptors.add(PrettyDioLogger(
requestHeader: true, requestBody: true, responseHeader: true));
}
return dio;
}
When I build my application for the first time the Constants.token has a blank value.
But in the middle of the application I wish to add a value into it. I am able to change that value but when I see the logs from dio logger it still displays the empty string in the "Authorisation" field.
How do I update my instance so that I can change my token value for my API requests?
you have to register your dio with registerFactory to getit. In your case you are registering as singleton, that's why it is giving you same instance
First you should create an interceptor that call TokenInterceptor with override onRequest method. Inside onRequest method you can modify your headers like below:
https://i.stack.imgur.com/T6PFR.png
And final step you only add to your dio interceptor like that:
dio.interceptors.add(TokenInterceptor());
final getIt = GetIt.instance;
void setupSingleton(){
getIt.allowReassignment=true;
}
//this should call first and then it will work

Could not set header with dio

I ma not able to set header with dio.I am tryng to set my access token to the header.I ma trying to set header so that every request doesnt required to call it.Here is my network class where i am trying to call header with dio
My network Class:
class NetworkUtil {
Dio _dio;
String token;
getToken() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
String getToken = preferences.getString(AppPrefernces.LOGIN_PREF);
return getToken;
}
NetworkUtil() {
///Create Dio Object using baseOptions set receiveTimeout,connectTimeout
BaseOptions options = BaseOptions(receiveTimeout: 5000, connectTimeout: 5000);
options.baseUrl = ApiConstants.BASE_URL;
_dio = Dio(options);
_dio.interceptors.add(InterceptorsWrapper(
onRequest: (Options option) async{
//my function to recovery token
await getToken().then((result) {
LoginResponse loginResponse = LoginResponse.fromJson(jsonDecode(result));
token = loginResponse.accessToken;
});
option.headers = {
"Authorization": "Bearer $token"
};
}
));
}
///used for calling Get Request
Future<Response> get(String url, Map<String, String> params) async {
Response response = await _dio.get(url,
queryParameters: params,
options: Options(responseType: ResponseType.json));
return response;
}
///used for calling post Request
Future<Response> post(String url, Map<String, String> params) async {
Response response = await _dio.post(url,
data: params, options: Options(responseType: ResponseType.json));
return response;
}
}
I use this setup and it works fine for me.
Future<Dio> createDioWithHeader() async {
if (_dioWithHeader != null) return _dioWithHeader;
String token = await appSharedPreferences.getToken();
String userAgent = await getUserAgent();
print('User-Agent: $userAgent');
// base config
_dioWithHeader = Dio(BaseOptions(
connectTimeout: 10000,
receiveTimeout: 10000,
baseUrl: Config.apiBaseUrl,
contentType: 'application/json',
headers: {
'Authorization': token,
'User-Agent': userAgent
}));
// setup interceptors
return addInterceptors(_dioWithHeader);
}```

Flutter cache mechanism for Dio retrofit sub library

i my application i'm using Dio's Retrofit sub library, and inside that i'm not sure how can i define cache mechanism for that,
i found this line in Retrofit sample code:
#GET("")
Future<String> testCustomOptions(#DioOptions() Options options);
now how can i define cache on this http request?
Retrofit documentation:
void main(List<String> args) {
final dio = Dio(); // Provide a dio instance
dio.options.headers["Demo-Header"] = "demo header"; // config your dio headers globally
final client = RestClient(dio);
client.getTasks().then((it) => logger.i(it));
dio-http-cache documentation:
QuickStart
Add a dio-http-cache interceptor in Dio :
dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: "http://www.google.com")).interceptor);
Set maxAge for a request :
Dio().get(
"http://www.google.com",
options: buildCacheOptions(Duration(days: 7)),
);
my full implemented code:
Provider(
create: (_) => MyApis.create(),
),
abstract class MyApis{
factory MyApis(Dio dio, {String baseUrl}) = _MyApis;
#GET("/login")
Future<HttpResponse<PageInformation>> login(#DioOptions() Options options);
static MyApis create() {
final dio = Dio();
dio.options.headers['Content-Type'] = 'application/json';
dio.options.receiveTimeout = 60000;
dio.options.connectTimeout = 120000;
return _MyApis(dio);
}
}
Add Parameter in your API Add point Call
Future<HttpResponse<PageInformation>> login(#DioOptions() Options options);
Add Interceptor in Dio
dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: 'YOUR BASE URL')).interceptor);
Create an object for Endpoint argument
Options options = buildCacheOptions(Duration(days: 10),forceRefresh: true);
Call your API End point
myapi.login(options)

Global configuration (interceptor) for dio in Flutter

First time with Flutter. I'm using dio to send HTTP requests, and I have to add a header to all requests, which I do with an interceptor, like this:
Dio dio = new Dio();
dio.interceptors.add(InterceptorsWrapper(
onRequest:(RequestOptions options) async {
options.headers["X-Requested-With"] = "XMLHttpRequest";
})
);
It works in main.dart, but if I want to import another class like MyHomePage.dart and do HTTP requests there, I'd have to redefine the interceptor in that class too.
How can I implement this interceptor for my whole application without adding it in every .dart file?
Create a function that houses the DIO and then call it where needed
Dio getDio() {
Dio dio = new Dio();
dio.interceptors.add(InterceptorsWrapper(onRequest: (RequestOptions options) async {
options.headers["X-Requested-With"] = "XMLHttpRequest";
}));
return dio;
}
This worked good for me, without interceptors, just create a class and use it in your app.
import 'package:dio/dio.dart';
import '../helpers/api_url.dart';
class dioClient {
Dio dio = Dio();
static Dio simpleDio() {
return Dio(BaseOptions(
baseUrl: apiUrl(),
headers: {'Content-Type': 'application/json; charset=UTF-8'}));
}
static Dio dioWithCookie(String cookie) {
return Dio(BaseOptions(baseUrl: apiUrl(), headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Cookie': cookie
}));
}
}