trevorwang / retrofit.dart

retrofit.dart is an dio client generator using source_gen and inspired by Chopper and Retrofit.
https://mings.in/retrofit.dart/
MIT License
1.06k stars 241 forks source link

How to solve DioException [unknown]: null #657

Open Kurogoma939 opened 5 months ago

Kurogoma939 commented 5 months ago

Describe the bug I'm using this API with Flutter and the API returns the following results.

log.json

so I have prepared the following Model classes.

@freezed
class HotpepperGourmetResponseResult with _$HotpepperGourmetResponseResult {
  factory HotpepperGourmetResponseResult({
    required HotpepperGourmetResponse results,
  }) = _HotpepperGourmetResponseResult;
  factory HotpepperGourmetResponseResult.fromJson(Map<String, dynamic> json) =>
      _$HotpepperGourmetResponseResultFromJson(json);
}
@freezed
class HotpepperGourmetResponse with _$HotpepperGourmetResponse {
  factory HotpepperGourmetResponse({
    @Default('') String apiVersion,
    @Default(0) int resultsAvailable,
    @Default('') String resultsReturned,
    @Default(0) int resultsStart,
    required List<Shop> shop,
  }) = _HotpepperGourmetResponse;

  factory HotpepperGourmetResponse.fromJson(Map<String, dynamic> json) =>
      _$HotpepperGourmetResponseFromJson(json);
}

and here is my retrofit code.

  @GET('')
  Future<HotpepperGourmetResponseResult> fetchHotpepperInfo({
    @Query('key') required String apiKey,
    @Query('format') required String format,
    @Query('lat') required double latitude,
    @Query('lng') required double longitude,
    @Query('range') required int range,
  });

when I call fetchHotpepperInfo the method return DioException [unknown]: null Because I change the method like this.

  @GET('')
  Future<String> fetchHotpepperInfo({
    @Query('key') required String apiKey,
    @Query('format') required String format,
    @Query('lat') required double latitude,
    @Query('lng') required double longitude,
    @Query('range') required int range,
  });
  @GET('')
  Future<HotpepperGourmetResponseResult> fetchHotpepperInfo({
    @Query('key') required String apiKey,
    @Query('format') required String format,
    @Query('lat') required double latitude,
    @Query('lng') required double longitude,
    @Query('range') required int range,
  });

When calling, I am writing it like this.

      final response = await hotpepperClient.fetchHotpepperInfo(
        apiKey: 'xxxxxxxxxx',
        format: 'json',
        latitude: 35.681236,
        longitude: 139.767125,
        range: 3,
      );

      final jsonData = jsonDecode(response) as Map<String, dynamic>;
      final result = HotpepperGourmetResponseResult.fromJson(jsonData);
      return result.results.shop;

However, with this kind of approach, I haven't been able to bring out the charm of Retrofit, and I couldn't find a solution. 😢

To Reproduce It is as indicated in the code.

Expected behavior A clear and concise description of what you expected to happen.

Screenshots It is as indicated in the code.

**Desktop (please complete I hope the function will work.

Smartphone (please complete the following information):

Additional context Is this inevitable, or is there something that can be configured to improve it?

Kurogoma939 commented 5 months ago

Sorry, my pubspec.yaml is here

environment:
  sdk: '>=3.2.3 <4.0.0'

dependencies:
  dio: ^5.4.0
  flutter:
    sdk: flutter
  freezed: ^2.4.7
  freezed_annotation: ^2.4.1
  json_annotation: ^4.8.1
  retrofit: ^4.1.0

dev_dependencies:
  build_runner: ^2.4.8
  json_serializable: ^6.7.1
  retrofit_generator: ^8.1.0

and here is the result of flutter doctor

[✓] Flutter (Channel stable, 3.16.9, on macOS 14.1 23B2073 darwin-arm64, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 15.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.86.1)
[✓] Connected device (2 available)
[✓] Network resources
notoriouscode97 commented 3 months ago

I'm having the exact same issue, was anyone able to fix this?

Kurogoma939 commented 3 months ago

Hi @notoriouscode97 ! I found a tentative solution.

💡 Please take a look at the headers in the API response.

Is the content type "text/plain" instead of "application/json"?

In that case, it seems that the Retrofit response model class needs to receive the response as a String, and then you have to jsonEncode it.

However, I would like to leave this issue as I would like to be able to use retrofit even when content-type is text.

notoriouscode97 commented 3 months ago

That was the issue, thank you!