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

toJson will not add if we use freezed. #682

Open
b14cknc0d3 opened this issue Jun 11, 2024 · 6 comments
Open

toJson will not add if we use freezed. #682

b14cknc0d3 opened this issue Jun 11, 2024 · 6 comments

Comments

@b14cknc0d3
Copy link

b14cknc0d3 commented Jun 11, 2024

Describe the bug
toJson will not add if we use freezed.
and show this warning

YourModel must provide a `toJson()` method which return a Map.

To Reproduce
Steps to reproduce the behavior:

  1. create a model with freezed
@freezed
class FoodTagCreateModel with _$FoodTagCreateModel {
  const factory FoodTagCreateModel({
    required String name,
    required String description,
  }) = _FoodTagCreateModel;

  factory FoodTagCreateModel.fromJson(Map<String, dynamic> json) =>
      _$FoodTagCreateModelFromJson(json);

}
  1. generate a ResApi client that use that model and run build runner
@RestApi()
abstract class CrudApi {
  factory CrudApi(Dio dio, {String? baseUrl}) = _CrudApi;

  @POST('/api/v1/my-model')
  Future<void> createAModel(@Body() MyModel body);
  1. See error
MyModel must provide a `toJson()` method which return a Map.
It is programmer's responsibility to make sure the MyModel is properly serialized

Expected behavior
If body is not Map force to add toJson() whether it has toJson() or not.

@b14cknc0d3 b14cknc0d3 changed the title toJson will not add if we exclude .g.dart in analysis_options toJson will not add if we use freezed. Jun 11, 2024
@b14cknc0d3
Copy link
Author

@freezed
class FoodTagCreateModel with _$FoodTagCreateModel {
  const factory FoodTagCreateModel({
    required String name,
    required String description,
  }) = _FoodTagCreateModel;

  factory FoodTagCreateModel.fromJson(Map<String, dynamic> json) =>
      _$FoodTagCreateModelFromJson(json);
  @override
  Map<String, dynamic> toJson() => toJson();
}

Temporary solution.

@fryette
Copy link

fryette commented Jun 25, 2024

Duplicate.
Correct solution is:

  1. Add build.yaml with next snippet
  freezed:
   runs_before:
     - json_serializable 
  json_serializable: 
     runs_before:
      - retrofit_generator

@lailai0715
Copy link

lailai0715 commented Aug 7, 2024

Duplicate. Correct solution is:

  1. Add build.yaml with next snippet
  freezed:
   runs_before:
     - json_serializable 
  json_serializable: 
     runs_before:
      - retrofit_generator

Not working in env flutter 3.24
build_runner: ^2.4.11
freezed: ^2.5.2
json_serializable: ^6.8.0
retrofit_generator: ^8.1.2
riverpod_generator: ^2.4.0

The generated retrofit class didn't auto insert toJson() from my freezed class

client.dart

part 'auth_client.g.dart';

@RestApi()
abstract class AuthClient {
  factory AuthClient(Dio dio, {required String baseUrl}) = _AuthClient;

  @POST("/members/login")
  Future<ApiResponse<LoginResponse?>> login(@Body() LoginBody body);
}

retrofit.g.dart

@override
  Future<ApiResponse<LoginResponse?>> login(LoginBody body) async {
    final _extra = <String, dynamic>{};
    final queryParameters = <String, dynamic>{};
    final _headers = <String, dynamic>{};
    /// toJson() is missing here
    final _data = body;
    final _result = await _dio.fetch<Map<String, dynamic>>(
        _setStreamType<ApiResponse<LoginResponse>>(Options(
      method: 'POST',
      headers: _headers,
      extra: _extra,
    )

login_body.dart

part 'login_body.freezed.dart';
part 'login_body.g.dart';

@Freezed()
sealed class LoginBody with _$LoginBody {
  const factory LoginBody({
    @JsonKey(name: "phone_no") String? phoneNo,
    String? password,
    String? email,
    String? otp,
    @JsonKey(name: "login_method")
    @Default(LoginMethod.phonePassword)
    LoginMethod loginMethod,
  }) = _LoginBody;

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

@nicolasWenia
Copy link

@freezed
class FoodTagCreateModel with _$FoodTagCreateModel {
  const factory FoodTagCreateModel({
    required String name,
    required String description,
  }) = _FoodTagCreateModel;

  factory FoodTagCreateModel.fromJson(Map<String, dynamic> json) =>
      _$FoodTagCreateModelFromJson(json);
  @override
  Map<String, dynamic> toJson() => toJson();
}

Temporary solution.

This worked for me but it'd be good to not have to do this to make the generator happy

@ToniVinter
Copy link

@lailai0715 , did you find a solution? I have the same problem

@lailai0715
Copy link

lailai0715 commented Aug 18, 2024

@lailai0715 , did you find a solution? I have the same problem

follow the temporary solution provided by @nicolasWenia , it's working in my project

Packages version used:
retrofit: ^4.1.0
retrofit_generator: ^8.1.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants