rrousselGit / freezed

Code generation for immutable classes that has a simple syntax/API without compromising on the features.
https://pub.dev/packages/freezed
1.87k stars 231 forks source link

Cannot get a _$MyClassToJson method outputted #513

Closed nyck33 closed 2 years ago

nyck33 commented 2 years ago

Describe the bug Please refer here: https://github.com/google/json_serializable.dart/issues/973

To Reproduce

The code is on the JsonSerializable issues.

Expected behavior I want a _$MyClassToJson method

nyck33 commented 2 years ago

Thank you rrouselGit. Did not want to use @ to save you time.

nyck33 commented 2 years ago

@rrousselGit FYI, Now I don't even bother putting a toJson method in my Freezed class because I could not solve the issue with upgrading versions of packages but oddly enough, I still have the toJson() method provided to me.
Below is an example of a User class and the line where I convert toJson:

//user.dart
///this is a test of another window

import 'dart:core';

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';
import 'dart:convert';

import './data_layer.dart';
import '../type_enums/enum_exports.dart';
import '../views/views_layer.dart';
import '../dummy_data/dummy_exports.dart';

part 'user.g.dart';
part 'user.freezed.dart';

///nested Task class to Json
///https://flutter.dev/docs/development/data-and-backend/json#manual-encoding
@freezed //(explicitToJson: true)
class User with _$User {
  User._();

  factory User({
    //@Default(CouponType.other) CouponType couponType, //->Enum for couponName
    required int userId,
    required String name,
    required String email,
    @Default(LoginStatus.loggedOut)
        LoginStatus loginStatus, //loggedIn or loggedOut
    @Default(CurrentScreen.homeScreen) CurrentScreen currentScreen,
    @Default('@DefaultHotel') String hotelName,
    @Default('-333') String roomNumber,
    DateTime? checkInDate,
    DateTime? checkOutDate,
    @Default(false) bool avatarExists,
    @Default(dummyImageUrl) String avatarUrl,
    @Default([]) List<Coupon> coupons, //set by Enum CouponType
  }) = _User;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
  //Map<String, dynamic> toJson() => _$couponToJson(this);

  //param coupon should be this when called
  Map<String, dynamic> myToJson(User user) {
    final int userId = user.userId;
    final String name = user.name;
    final String email = user.email;
    final String loginStatus = describeEnum(user.loginStatus);
    final String currentScreen = describeEnum(user.currentScreen);
    final String hotel = user.hotelName;
    final String room = user.roomNumber;
    final String? checkInDate = user.checkInDate?.toString() ?? 'AD 7';
    final String? checkOutDate = user.checkOutDate?.toString() ?? 'AD 3000';
    final bool avatarExists = user.avatarExists;
    final String avatarUrl = user.avatarUrl;
    final List<Coupon> coupons = user.coupons;

    //use Coupon instance to call myToJson
    //final Coupon coupon = Coupon();
    List couponsList = [];

    for (Coupon c in coupons) {
      final coupon_json = c.myToJson(c.copyWith());
      couponsList.add(coupon_json);
    }

    final Map<String, dynamic> user_json = {
      'userId': userId,
      'name': name,
      'email': email,
      'loginStatus': loginStatus,
      'currentScreen': currentScreen,
      'hotel': hotel,
      'room': room,
      'checkInDate': checkInDate,
      'checkOutDate': checkOutDate,
      'avatarExists': avatarExists,
      'avatarUrl': avatarUrl,
      'coupons': couponsList
    };

    return user_json;
  }

  //String get couponType => descri{beEnum(this.couponType);
  int get userId => this.userId;
  String get name => this.name;
  String get email => this.email;
  LoginStatus get loginStatus => this.loginStatus;
  CurrentScreen get currentScreen => this.currentScreen;
  String get hotelName => this.hotelName;
  String get roomNumber => this.roomNumber;
  DateTime? get checkInDate => this.checkInDate;
  DateTime? get checkOutDate => this.checkOutDate;
  bool get avatarExists => this.avatarExists;
  String get avatarUrl => this.avatarUrl;
  List<Coupon> get coupons => this.coupons;
}
//somwhere in main.dart
Map<String, dynamic> userMap;

  if (userJson == null) {
    //Navigator.pushNamed(context, '/login');
    //load dummy for now
    userMap = dummyUser.toJson();
  } else {
    try {
      userMap = jsonDecode(userJson);
    } catch (e) {
      print('error loading user from repo: $e');
      userMap = dummyUser.toJson();
    }
  }
//dummyUser object is a mock user object
import 'package:coupon_app/views/views_layer.dart';

import '../models/data_layer.dart';
import '../type_enums/enum_exports.dart';

//dummy user with 3 coupons
Coupon c1 = Coupon(
  couponId: 0,
  couponType: CouponType.breakfast,
  hotelName: 'Hilton Amsterdam',
  expiryDate: DateTime.utc(2100, 1, 1),
  couponAmount: CouponAmount.yen500,
  usedOn: null,
  isUsed: false,
  imageExists: false,
  details: 'This coupon can be used at the continental breakfast buffet',
  imageUrl: '',
  couponName: '',
);

Coupon c2 = Coupon(
    couponId: 1,
    couponType: CouponType.dinner,
    hotelName: 'Hilton Amsterdam',
    expiryDate: DateTime.utc(2100, 1, 1),
    couponAmount: CouponAmount.yen1000,
    usedOn: null,
    isUsed: false,
    imageExists: false,
    details: 'This coupon can be used at the buffet dinner with live music',
    imageUrl: '',
    couponName: '');

Coupon special = Coupon(
    couponId: 2,
    couponType: CouponType.other,
    hotelName: 'Hilton Amsterdam',
    expiryDate: DateTime.utc(2100, 1, 1),
    couponAmount: CouponAmount.yen1000,
    usedOn: null,
    isUsed: false,
    imageExists: false,
    details:
        'This coupon can be used at the nightly Wine and Cheese with host Oprah Winfrey',
    imageUrl: 'assets/images/apaSpecial.png',
    couponName: 'スペシャルクーポン'
    //imageUrl: getImageUrl(this.couponAmount);
    );

List<Coupon> dummyCoupons = [c1, c2, special];
User dummyUser = User(
    userId: 0,
    name: 'Nobu Kim',
    email: 'nobu.kim66@gmail.com',
    loginStatus: LoginStatus.loggedIn,
    currentScreen: CurrentScreen.homeScreen,
    hotelName: 'Hilton Amsterdam',
    roomNumber: '33',
    checkInDate: DateTime.utc(1976, 5, 31),
    checkOutDate: DateTime.utc(2100, 5, 31),
    avatarExists: false,
    avatarUrl: '',
    coupons: dummyCoupons);
Silfalion commented 2 years ago

If anyone stumble upon this and needs to customize the output of the toJson, the method I used is to add a separate toJsonSomething to the class then following the Custom getters and methods section described here in the repo.