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

Type cast error when using FactoryConverter #631

Closed
TheLastFlame opened this issue Aug 27, 2024 · 3 comments
Closed

Type cast error when using FactoryConverter #631

TheLastFlame opened this issue Aug 27, 2024 · 3 comments
Assignees
Labels
documentation Documentation related

Comments

@TheLastFlame
Copy link

Steps to Reproduce

Use FactoryConverter for a request with the specified response type.

Expected results:
Correct behavior similar to global converter usage

Actual results:
type 'List' is not a subtype of type 'Response<List<Map<String, dynamic>>>' in type cast

Code sample
@ChopperApi()
abstract class API extends ChopperService {
  static API create() {
    final client = ChopperClient(
      baseUrl: Uri.parse(url),
      converter: const JsonConverter(),
      errorConverter: const JsonConverter(),
    );
    return _$AuthorTodayAPI(client);
  }
  @FactoryConverter(response: convertResponse)
  @Get(path: path)
  Future<Response<List<Map<String, dynamic>>>> fetch();
}

FutureOr<Response<T>> convertResponse<T>(Response res) =>
    const JsonConverter().convertResponse(res);
Logs
type 'List<dynamic>' is not a subtype of type 'Response<List<Map<String, dynamic>>>' in type cast
No issues found!
Dart SDK version: 3.5.0 (stable) (Tue Jul 30 02:17:59 2024 -0700) on "windows_x64"
@TheLastFlame TheLastFlame added the bug Something isn't working label Aug 27, 2024
@techouse techouse added question Further information is requested and removed bug Something isn't working labels Sep 5, 2024
@techouse
Copy link
Collaborator

techouse commented Sep 5, 2024

Hi, can you please provide an example / repo which reproduces this error?

@techouse techouse self-assigned this Sep 5, 2024
@techouse techouse added investigation The issue needs further investigation bug Something isn't working labels Sep 5, 2024
@TheLastFlame
Copy link
Author

TheLastFlame commented Sep 7, 2024

Hi, can you please provide an example / repo which reproduces this error?

Is it possibly related to #173?

Hi. Unfortunately, I've already over-worked that code and I don't have any copies left.
I created a new project to demonstrate it, but I got a different behaviour.
Now I get this error even without FactoryConverter.

I'll try to investigate this further when I have more free time.

@techouse techouse removed the bug Something isn't working label Sep 9, 2024
@techouse techouse removed their assignment Oct 24, 2024
@techouse
Copy link
Collaborator

techouse commented Feb 11, 2025

I was able to reproduce this with the following code snippet

import 'dart:async';
import 'package:chopper/chopper.dart';

part 'api.chopper.dart';

@ChopperApi()
abstract class ApiService extends ChopperService {
  static ApiService create([ChopperClient? client]) =>
      _$ApiService(client);

  @FactoryConverter(response: convertResponse)
  @GET(path: 'v2/breaches')
  Future<Response<List<Map<String, dynamic>>>> fetch();

  static FutureOr<Response<T>> convertResponse<T>(Response res) =>
      const JsonConverter().convertResponse(res);
}

Future<void> main() async {
  final chopper = ChopperClient(
    baseUrl: Uri.parse('https://haveibeenpwned.com/api/'),
    services: [
      ApiService.create(ChopperClient()),
    ],
    converter: JsonConverter(),
    errorConverter: const JsonConverter(),
  );

  final apiService = chopper.getService<ApiService>();

  final response = await apiService.fetch();
  print(response.body);

  chopper.dispose();
}

Which throws

Unhandled exception:
type 'CastList<dynamic, dynamic>' is not a subtype of type 'List<Map<String, dynamic>>?'

@TheLastFlame in order to fix it you have to provide the List's inner type

  static FutureOr<Response<T>> convertResponse<T>(Response res) =>
      const JsonConverter().convertResponse<
          T,
          Map<String, dynamic> // <-- you need to provide the inner type
      >(res);

Which would then summount to

@ChopperApi()
abstract class ApiService extends ChopperService {
  static ApiService create([ChopperClient? client]) => _$ApiService(client);

  @FactoryConverter(response: convertResponse)
  @GET(path: 'v2/breaches')
  Future<Response<List<Map<String, dynamic>>>> fetch();

  static FutureOr<Response<T>> convertResponse<T, Q extends Map<String, dynamic>>(Response res) =>
      const JsonConverter().convertResponse<T, Q>(res);
}

@techouse techouse self-assigned this Feb 11, 2025
@techouse techouse added documentation Documentation related and removed question Further information is requested investigation The issue needs further investigation labels Feb 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Documentation related
Projects
None yet
Development

No branches or pull requests

2 participants