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.08k stars 248 forks source link

Return type as a freezed union #524

Open aidanmack opened 1 year ago

aidanmack commented 1 year ago

Is your feature request related to a problem? Please describe. Yes - Im trying to return my own api return type using Freezed unions.

Describe the solution you'd like

I want to be able create api requests in Retrofit like this where NetworkResponse is of type Freezed Union

 @override
  @POST("/gettoken")
  Future<NetworkResponse<TokenApprove>> signUp(@Body() SendSignUpCredentials signUpCredentials);

The problem is my NetworkResponse data payload needs to be a generic, but then I also need to change the json into the TokenApprove object and I'm not confident with where this should happen.

Right now I'm trying to convert it in the method NetworkResponse.fromJson ... But I'm not sure how that function will know how to change the json to TokenApprove

@Freezed(genericArgumentFactories: true)
class NetworkResponse<T> with _$NetworkResponse {
  const factory NetworkResponse.success(T data) = Ok;
  const factory NetworkResponse.error(BadRequestResponse message) = ERROR;

//This works when we want to just convert json to string!
  //factory NetworkResponse.fromJson(Map<String, dynamic> json){
 //   return NetworkResponse.success(json.toString() as T);
  //}

  factory NetworkResponse.fromJson(
      Map<String, dynamic> json,
      T Function(Object? json) fromJsonT,
      ) =>
      _$NetworkResponseFromJson<T>(json, fromJsonT);
}

Describe alternatives you've considered Yeah I've got a static function that once a resonse is returned from the api converts Future to my NetworkResponse union. Not ideal though really.

aidanmack commented 1 year ago

Never mind!

I think the fix for my above question would be to write the fromJson as

factory NetworkResponse.fromJson(
    Map<String, dynamic> json,
    T Function(Object? json) fromJsonT,
  ) => NetworkResponse.success(fromJsonT.call(json));