DIo not working while adding extras in requestOptions with path in Dio singleton
parmeetmaster opened this issue · 3 comments
parmeetmaster commented
Package
dio
Version
dio: ^5.4.3+1
Operating-System
Android
Adapter
Default Dio
Output of flutter doctor -v
I/flutter (28646): ╔╣ Request ║ POST
I/flutter (28646): ║ https://stgapp.***.com/sales-**-stg/smaPropertyBased/0
I/flutter (28646): ╚══════════════════════════════════════════════════════════════════════════════════════════╝
I/flutter (28646): ╔ Headers
I/flutter (28646): ╟ content-type: application/json
I/flutter (28646): ╟ clientId: SMP100475
I/flutter (28646): ╟ latitude: 22.6388417
I/flutter (28646): ╟ Longitude: 72.082512
I/flutter (28646): ╟ token:
I/flutter (28646): ║ eyJhbGciOiJSUzI1NiIsImkiOkpXVCJ9.eyJzdWIiOiJTTVAxMDA2NDkiLCJlIjoicGFybWVld
I/flutter (28646): ║ C5zaW5naEBzcGljZW1vbmV5LmNvbSIsImlU1BJQ0VfaW1wYWN0IiwiZXhwIjoxNzE3MjM0NTY4LCJtIjo
I/flutter (28646): ║ iOTg3MTkxNzUxNSIsImlhdCI6MTcxNzIzNDI2OH0.XD7Ll8vwL5LtJcN_RB8y_8UeCh3jEl9c5a-fAmgEA8JJwQLFj
I/flutter (28646): ║ _lOmVD0P1n-ViEUcKOBjDZN_77s_bfjiYZYLA2xhkNueH83ttBLjkMckxWH7cNYVYqlJHb-S3_ML1F166Y2cv5EEvu
I/flutter (28646): ║ yp0n_4QVQ95aXE24nJs4HRR_b9vArfsnTc-Nb3dVOTT35mmgd5m2UR8ENUj4MT9yj5FD3TxNZQHAOSzJ8AwOCZwWqR
I/flutter (28646): ║ HgFUz3C9usocEX8Is--amAvWKewPn9kfUobjC4kKaUSSYFhkbOdGrVHPBBOXiIRPbBivMwLjf1VD2XZjSyfE59UPh_
I/flutter (28646): ║ EtXM5rZLb7K9ExiR4BbZvHA
I/flutter (28646): ╟ r-token: ****
I/flutter (28646): ║ eyJhbGciOiJSUzAxMDA2NDkiLCJlIjoicGFybWVld
I/flutter (28646): ║ C5zaW5naEBzcGljZW1vbmV5LmNvbSIsImlzcyI6IlJfU1BJQ0VfaW1wYWN0IiwiZXhwIjoxNzI1MDEwMjY4LCJtIjo
I/flutter (28646): ║ iOTg3MTkxNzUxNSIsImlhdCI6MTcxNzIzNDI2OH0.GXtiCiDHO7xF898zRhYVhMCC5grOyfYjotjhzQyS_0-6-sSI8
I/flutter (28646): ║ H_X2M1KhlpJbUJ7xJ-ByFV3YsU4ht14E7Sq99yJjx13JvxY348jQPseHaljrmnxg_ZgbYM-gxTTiAeAQBPvicsACcM
I/flutter (28646): ║ 0E-JmAN2KdPBwrOsl53QdZaKb4A0ahvLuQqDsxRLGvkabe6djQoZEGDYg3XOmgF8Ulq19_s-oj7JWsb6UFgJuIHDQZ
I/flutter (28646): ║ Z5OdNIiUWKsb21GangDdLuHX83H9uf4aFEW3LPhHao_l3uUXV5pyZN-WjdaICGgzzFnpOErzTz_w2uvzOi8D5Cal0T
I/flutter (28646): ║ -tSeT7gsFY8i_R7f4C2cCXQ
I/flutter (28646): ╟ appVer: 2.0.12
I/flutter (28646): ╟ userRole: Cluster
I/flutter (28646): ╟ lang: en
I/flutter (28646): ╟ contentType: application/json
I/flutter (28646): ╟ responseType: ResponseType.json
I/flutter (28646): ╟ followRedirects: true
I/flutter (28646): ╟ connectTimeout: 0:00:30.000000
I/flutter (28646): ╟ receiveTimeout: null
I/flutter (28646): ╚══════════════════════════════════════════════════════════════════════════════════════════╝
I/flutter (28646): ╔ Extras
I/flutter (28646): ╟ date: 2024-06-01 15:31:34.913083
I/flutter (28646): ╚══════════════════════════════════════════════════════════════════════════════════════════╝
I/flutter (28646): ╔ Body
I/flutter (28646): ╟ cluster:
I/flutter (28646): ╟ distId: null
I/flutter (28646): ╟ requestType: monthly
I/flutter (28646): ╟ pincode:
I/flutter (28646): ╟ filterBy:
I/flutter (28646): ╟ totalSma:
I/flutter (28646): ╚══════════════════════════════════════════════════════════════════════════════════════════╝
I/flutter (28646): ║ {, cluster: , distId:
I/flutter (28646): ║ null, requestType: monthly, pincode: , filterBy: , totalSma: }
I/flutter (28646): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (28646): │ #0 mstrings.printwtf (package:spice_impact_new/utils/logs.dart:12:29)
I/flutter (28646): │ #1 UserExperiaDioInterceptor.onRequest (package:spice_impact_new/data/datasources/network/modules/user_experia_dio_interceptor.dart:16:50)
I/flutter (28646): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter (28646): │ 👾 @#experia request /smaPropertyBased/0
I/flutter (28646): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (28646):
I/flutter (28646): ╔╣ DioError ║ DioExceptionType.unknown
I/flutter (28646): ║ null
I/flutter (28646): ╚══════════════════════════════════════════════════════════════════════════════════════════╝
I/flutter (28646): ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/flutter (28646): │ #0 mstrings.printwtf (package:spice_impact_new/utils/logs.dart:12:29)
I/flutter (28646): │ #1 UserExperiaDioInterceptor.onError (package:spice_impact_new/data/datasources/network/modules/user_experia_dio_interceptor.dart:25:64)
I/flutter (28646): ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
I/flutter (28646): │ 👾 @#experia error {date: 2024-06-01 15:31:34.913083}
I/flutter (28646): └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
I/TRuntime.CctTransportBackend(28646): Making request to: https://firebaselogging-pa.googleapis.com/v1/firelog/legacy/batchlog
I/TRuntime.CctTransportBackend(28646): Status Code: 200
I/UserExperiorLogs(28646): idle
I/UserExperiorLogs(28646): R -- P
I/UserExperiorLogs(28646): R -- R
Dart Version
dio: ^5.4.3+1
Steps to Reproduce
I am adding extras in dio.post
Future<d.Response> post(String path, Map<String, dynamic> data,
{String? baseUrl = null, d.CancelToken? cancelToken,UserExperiaModel? userExperiaModel}) async {
if (dio == null) {
await _initalised();
}
d.Options? requestOptions;
if(userExperiaModel!=null){
requestOptions=d.Options(
extra:{"date":DateTime.now()});
}
dio!.options.contentType = "application/json";
d.Response response =
await dio!.post(path ,options: requestOptions, data: data, cancelToken: cancelToken);
return response;
}
Expected Result
Result should be json response that i use to sent data.
Actual Result
I am getting null while adding extras without that it works fine
AlexV525 commented
extra
does not involved with any computation of the request. Could you attach a minimal reproducible example?
parmeetmaster commented
/*
* Copyright © 2023, This code is developed by
* Under work enviorment of tata money.Sharing and distributor source code outside organisaton is prohibited.
*/
import 'dart:io';
import 'package:colorize/colorize.dart';
import 'package:dio/dio.dart' as d;
import 'package:dio/dio.dart';
import 'package:dio_smart_retry/dio_smart_retry.dart';
import 'package:file_support/file_support.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import 'package:tata_impact_new/data/datasources/local/services/file_service.dart';
import 'package:tata_impact_new/data/datasources/network/modules/enviorment_module.dart';
import 'package:tata_impact_new/data/datasources/network/modules/user_experia_dio_interceptor.dart';
import 'package:tata_impact_new/data/datasources/network/services/user_experior_service.dart';
import 'package:tata_impact_new/data/datasources/network/utils/dio_performance_adapter.dart';
import 'package:tata_impact_new/data/datasources/network/utils/handle_response.dart';
import 'package:tata_impact_new/data/models/user_experia_model.dart';
import 'package:tata_impact_new/data/repositories/core/i_core_data_repo.dart';
import 'package:tata_impact_new/data/repositories/firebase_analytics_events/i_firebase_analytics_event.dart';
import 'package:tata_impact_new/dependency_injection/inject.dart';
import 'package:tata_impact_new/utils/utils.dart';
import 'package:uuid/uuid.dart';
import '../../../../utils/FLocation.dart';
import '../../local/services/kv_storage_service.dart';
import 'package:uuid/uuid.dart' as uuid;
/*---------------------------------Interceptors ---------------------------*/
class MasterInterceptor extends d.Interceptor {
final showToken = true;
@override
void onRequest(
RequestOptions options, RequestInterceptorHandler handler) async {
MEnviorment enviorment = getIt<MEnviorment>();
String? _token = await getIt<KVStorageService>().accessToken;
String? _rToken = await getIt<KVStorageService>().refreshToken;
options.connectTimeout = const Duration(seconds: 30);
if (_token != null || _rToken != null) {
_token!.printinfo;
_rToken!.printinfo;
}
if (showToken && (enviorment.env == ENVIORMENT.debug)) {
color("TOKEN: ${_token}\n",
front: Styles.BG_GREEN,
isBold: true,
isItalic: false,
isUnderline: false);
color("R-TOKEN: ${_rToken}\n",
front: Styles.BG_BLUE,
isBold: true,
isItalic: false,
isUnderline: false);
}
/* String lat = kReleaseMode
? Flocation.instance.locationData?.latitude.toString() ?? ""
: "25.98217";
String long = kReleaseMode
? Flocation.instance.locationData?.longitude.toString() ?? ""
: "80.10131";*/
String lat = Flocation.instance.locationData?.latitude.toString() ?? "";
String long = Flocation.instance.locationData?.longitude.toString() ?? "";
//package
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String _version = packageInfo.version;
// clientId
String role = "";
try {
role = getIt<ICoreDataRepo>().coreData.role;
} catch (e) {
role = "";
}
options.headers.addAll({
'clientId': getIt<ICoreDataRepo>().clientId ?? "",
'latitude': lat ?? "",
'Longitude': long ?? "",
'token': _token ?? "",
'r-token': _rToken ?? "",
'appVer': _version,
'userRole': role,
'lang': "en",
'merchant': "IMPACT",
});
print("sending data ${options.headers.toString()}");
return super.onRequest(options, handler); // its required to add
}
@override
void onError(d.DioException err, ErrorInterceptorHandler handler) {
if (err.response!.statusCode == 403) {
print("seassion expire");
} else if (err.response!.statusCode == 400) {
getIt<IFireBaseAnalyticsEventRepo>().apiRecord400Error(
(err.response?.requestOptions.baseUrl ?? "") +
(err.response?.requestOptions.path ?? ""));
}
return handler.next(err);
}
@override
void onResponse(
d.Response response, ResponseInterceptorHandler handler) async {
if (response.statusCode == 400) {
getIt<IFireBaseAnalyticsEventRepo>().apiRecord400Error(
(response.requestOptions.baseUrl ?? "") +
(response.requestOptions.path ?? ""));
}
return super.onResponse(response, handler);
}
}
class AuthenticationInterceptor extends d.Interceptor {
final showToken = true;
// this is not staging ot prod url its other Url that is using for authentication
static const LOGIN_API_ENDPOINT =
"https://dl.tatamoney.com/auth/gouth/impact/app";
static const LOGIN_WITH_EMAIL_API_ENDPOINT =
"https://dl.tatamoney.com/auth/loginStore/impact/app";
static const LOGIN_WITH_STAGING_API_ENDPOINT =
"https://stgapp.tatamoney.com/impact-auth/gouth/impact/app";
@override
void onResponse(
d.Response response, ResponseInterceptorHandler handler) async {
if (((response.requestOptions.baseUrl + response.requestOptions.path)
.contains(LOGIN_API_ENDPOINT) ||
(response.requestOptions.baseUrl + response.requestOptions.path)
.contains(LOGIN_WITH_EMAIL_API_ENDPOINT)) ||
(response.requestOptions.baseUrl + response.requestOptions.path)
.contains(LOGIN_WITH_STAGING_API_ENDPOINT) &&
response.statusCode == 200) {
String _token = response.headers["token"]?.first ?? "null";
String _rToken = response.headers["r-token"]?.first ?? "null";
await getIt<KVStorageService>().setAccessToken(_token);
await getIt<KVStorageService>().setRefreshToken(_rToken);
//await getIt<AuthInterceptor>().initialize();
}
return super.onResponse(response, handler);
}
}
/*Client logic*/
class DioClient with HandleApiResultMixin {
late KVStorageService _kvStorageService;
d.Dio? dio;
String baseUrl;
String stagingUrl;
DioClient({required this.baseUrl, required this.stagingUrl}) {
_initalised();
}
_initalised() async {
MEnviorment menviorment = getIt<MEnviorment>();
if (menviorment.env == ENVIORMENT.prod) {
baseUrl = baseUrl;
} else {
baseUrl = stagingUrl;
}
dio = d.Dio();
dio!.options.baseUrl = baseUrl;
dio!.interceptors.addAll(
[
/* RetryInterceptor(
dio: dio!,
logPrint: print, // specify log function (optional)
retries: 3, // retry count (optional)
retryDelays: const [
Duration(seconds: 5),
Duration(seconds: 10),
Duration(seconds: 30),
],
),*/
UserExperiaDioInterceptor(),
AuthenticationInterceptor(),
MasterInterceptor(),
DioFirebasePerformanceInterceptor(),
PrettyDioLogger(
requestHeader: true,
requestBody: true,
error: true,
responseBody: true,
responseHeader: false,
compact: false,
),
],
);
}
Future<d.Response> get(String path, Map<String, dynamic> queryparms,
{d.CancelToken? cancelToken,UserExperiaModel? userExperiaModel}) async {
if (dio == null) {
await _initalised();
}
d.Response response = await dio!
.get(path, queryParameters: queryparms, cancelToken: cancelToken);
return response;
}
@AlexV525 pls focus this i am adding here extras.
Future<d.Response> post(String path, Map<String, dynamic> data,
{String? baseUrl = null, d.CancelToken? cancelToken,UserExperiaModel? userExperiaModel}) async {
if (dio == null) {
await _initalised();
}
if(userExperiaModel!=null){
userExperiaModel=userExperiaModel.copyWith(properties: userExperiaModel.properties.copyWith(requestBody: data.toString()));
dio!.options.copyWith(extra: userExperiaModel.toJson());
}
dio!.options.contentType = "application/json";
d.Response response =
await dio!.post(path , data: data, cancelToken: cancelToken);
return response;
}
Future<d.Response> postWithQueryParameters(
String path, Map<String, dynamic> data,
{Map<String, dynamic>? queryParams}) async {
if (dio == null) {
await _initalised();
}
dio!.options.contentType = "application/json";
d.Response response =
await dio!.post(path, queryParameters: queryParams, data: data);
return response;
}
Future<d.Response> postFormDataWithQueryParameters(
String path, Map<String, dynamic> data,
{Map<String, dynamic>? queryParams}) async {
dio!.options.contentType = "multipart/form-data";
if (dio == null) {
await _initalised();
}
return await dio!.post(path,
queryParameters: queryParams, data: d.FormData.fromMap(data));
}
//post raw data
Future<d.Response> postRawDataWithQueryParameters(String path,
{required Map<String, dynamic> queryParams,
required Map<String, dynamic> data}) async {
if (dio == null) {
await _initalised();
}
return await dio!.post(path, queryParameters: queryParams, data: data);
}
// post form data
Future<d.Response> postFormData(
String path, Map<String, dynamic> data) async {
dio!.options.contentType = "multipart/form-data";
if (dio == null) {
await _initalised();
}
return await dio!.post(
path,
data: d.FormData.fromMap(data),
);
}
/// used to take compress image form multipart
Future<d.MultipartFile> getMultiPartImage(File file) async {
"FILE PATH: ${file.path}".printinfo;
File? compressFile = await FileSupport().compressImage(file, quality: 50);
final d.MultipartFile multipart = await d.MultipartFile.fromFile(file.path);
return multipart;
}
Future<d.MultipartFile> getMultiPartImageCompressed(File file) async {
"FILE PATH: ${file.path}".printinfo;
File? compressFile = await getIt<FileService>().getCompressImage(file);
d.MultipartFile multipart =
await d.MultipartFile.fromFile(compressFile.path);
return multipart;
}
Future<d.MultipartFile> getMultiPart(File file) async {
"FILE PATH: ${file.path}".printinfo;
d.MultipartFile multipart = await d.MultipartFile.fromFile(file.path);
return multipart;
}
Future<DioClient> init() async {
await _initalised();
return this;
}
}
AlexV525 commented
Your code involves too many unrelated implementations and they are also inaccessible to us. Please make a minimal example to reproduce your case.