Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DIo not working while adding extras in requestOptions with path in Dio singleton #2229

Closed
parmeetmaster opened this issue Jun 1, 2024 · 3 comments

Comments

@parmeetmaster
Copy link

parmeetmaster commented Jun 1, 2024

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

image

I am getting null while adding extras without that it works fine

@parmeetmaster parmeetmaster added h: need triage This issue needs to be categorized s: bug Something isn't working labels Jun 1, 2024
@AlexV525
Copy link
Member

AlexV525 commented Jun 1, 2024

extra does not involved with any computation of the request. Could you attach a minimal reproducible example?

@parmeetmaster
Copy link
Author

parmeetmaster commented Jun 1, 2024

/*
 * 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
Copy link
Member

AlexV525 commented Jun 4, 2024

Your code involves too many unrelated implementations and they are also inaccessible to us. Please make a minimal example to reproduce your case.

@AlexV525 AlexV525 added the h: need more info Further information is requested label Jun 4, 2024
@AlexV525 AlexV525 closed this as not planned Won't fix, can't repro, duplicate, stale Jun 17, 2024
@AlexV525 AlexV525 added i: no useful information and removed h: need more info Further information is requested h: need triage This issue needs to be categorized s: bug Something isn't working labels Jun 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants