flutterdartfreezedjson-serializable

How to properly use freezed in dart/flutter


I want to convert a Json with Freezed package in Dart/Flutter.

my json:

{"rates":{"btc":{"name":"Bitcoin","unit":"BTC","value":1.0,"type":"crypto"},"eth":{"name":"Ether","unit":"ETH","value":18.737,"type":"crypto"},"ltc":{"name":"Litecoin","unit":"LTC","value":747.585,"type":"crypto"},"bch":{"name":"Bitcoin Cash","unit":"BCH","value":194.048,"type":"crypto"},"bnb":{"name":"Binance Coin","unit":"BNB","value":150.81,"type":"crypto"},"eos":{"name":"EOS","unit":"EOS","value":67935.089,"type":"crypto"},"xrp":{"name":"XRP","unit":"XRP","value":95155.791,"type":"crypto"},"xlm":{"name":"Lumens","unit":"XLM","value":453990.358,"type":"crypto"},"link":{"name":"Chainlink","unit":"LINK","value":2609.98,"type":"crypto"},"dot":{"name":"Polkadot","unit":"DOT","value":6656.935,"type":"crypto"},"yfi":{"name":"Yearn.finance","unit":"YFI","value":6.75,"type":"crypto"},"usd":{"name":"US Dollar","unit":"$","value":52306.065,"type":"fiat"},"aed":{"name":"United Arab Emirates Dirham","unit":"DH","value":192111.287,"type":"fiat"},"ars":{"name":"Argentine Peso","unit":"$","value":43620885.106,"type":"fiat"},"aud":{"name":"Australian Dollar","unit":"A$","value":80483.238,"type":"fiat"},"bdt":{"name":"Bangladeshi Taka","unit":"৳","value":5730141.222,"type":"fiat"},"bhd":{"name":"Bahraini Dinar","unit":"BD","value":19714.26,"type":"fiat"},"bmd":{"name":"Bermudian Dollar","unit":"$","value":52306.065,"type":"fiat"},"brl":{"name":"Brazil Real","unit":"R$","value":259961.146,"type":"fiat"},"cad":{"name":"Canadian Dollar","unit":"CA$","value":70827.12,"type":"fiat"},"chf":{"name":"Swiss Franc","unit":"Fr.","value":46186.413,"type":"fiat"},"clp":{"name":"Chilean Peso","unit":"CLP$","value":50204408.056,"type":"fiat"},"cny":{"name":"Chinese Yuan","unit":"¥","value":372408.727,"type":"fiat"},"czk":{"name":"Czech Koruna","unit":"Kč","value":1235495.426,"type":"fiat"},"dkk":{"name":"Danish Krone","unit":"kr.","value":363157.719,"type":"fiat"},"eur":{"name":"Euro","unit":"€","value":48715.515,"type":"fiat"},"gbp":{"name":"British Pound Sterling","unit":"£","value":41686.312,"type":"fiat"},"gel":{"name":"Georgian Lari","unit":"₾","value":138872.604,"type":"fiat"},"hkd":{"name":"Hong Kong Dollar","unit":"HK$","value":409041.28,"type":"fiat"},"huf":{"name":"Hungarian Forint","unit":"Ft","value":18951574.97,"type":"fiat"},"idr":{"name":"Indonesian Rupiah","unit":"Rp","value":816333269.559,"type":"fiat"},"ils":{"name":"Israeli New Shekel","unit":"₪","value":189749.93,"type":"fiat"},"inr":{"name":"Indian Rupee","unit":"₹","value":4343668.469,"type":"fiat"},"jpy":{"name":"Japanese Yen","unit":"¥","value":7848695.164,"type":"fiat"},"krw":{"name":"South Korean Won","unit":"₩","value":69685263.504,"type":"fiat"},"kwd":{"name":"Kuwaiti Dinar","unit":"KD","value":16116.178,"type":"fiat"},"lkr":{"name":"Sri Lankan Rupee","unit":"Rs","value":16348295.799,"type":"fiat"},"mmk":{"name":"Burmese Kyat","unit":"K","value":109628916.276,"type":"fiat"},"mxn":{"name":"Mexican Peso","unit":"MX$","value":893162.687,"type":"fiat"},"myr":{"name":"Malaysian Ringgit","unit":"RM","value":250049.147,"type":"fiat"},"ngn":{"name":"Nigerian Naira","unit":"₦","value":79274550.235,"type":"fiat"},"nok":{"name":"Norwegian Krone","unit":"kr","value":553323.953,"type":"fiat"},"nzd":{"name":"New Zealand Dollar","unit":"NZ$","value":85818.875,"type":"fiat"},"php":{"name":"Philippine Peso","unit":"₱","value":2925609.024,"type":"fiat"},"pkr":{"name":"Pakistani Rupee","unit":"₨","value":14578223.75,"type":"fiat"},"pln":{"name":"Polish Zloty","unit":"zł","value":211703.518,"type":"fiat"},"rub":{"name":"Russian Ruble","unit":"₽","value":4811965.565,"type":"fiat"},"sar":{"name":"Saudi Riyal","unit":"SR","value":196165.112,"type":"fiat"},"sek":{"name":"Swedish Krona","unit":"kr","value":548320.826,"type":"fiat"},"sgd":{"name":"Singapore Dollar","unit":"S$","value":70481.9,"type":"fiat"},"thb":{"name":"Thai Baht","unit":"฿","value":1891095.47,"type":"fiat"},"try":{"name":"Turkish Lira","unit":"₺","value":1608285.988,"type":"fiat"},"twd":{"name":"New Taiwan Dollar","unit":"NT$","value":1640867.488,"type":"fiat"},"uah":{"name":"Ukrainian hryvnia","unit":"₴","value":1992749.746,"type":"fiat"},"vef":{"name":"Venezuelan bolívar fuerte","unit":"Bs.F","value":5237.406,"type":"fiat"},"vnd":{"name":"Vietnamese đồng","unit":"₫","value":1279502893.807,"type":"fiat"},"zar":{"name":"South African Rand","unit":"R","value":994222.714,"type":"fiat"},"xdr":{"name":"IMF Special Drawing Rights","unit":"XDR","value":39393.476,"type":"fiat"},"xag":{"name":"Silver - Troy Ounce","unit":"XAG","value":2311.686,"type":"commodity"},"xau":{"name":"Gold - Troy Ounce","unit":"XAU","value":26.191,"type":"commodity"},"bits":{"name":"Bits","unit":"μBTC","value":1000000.0,"type":"crypto"},"sats":{"name":"Satoshi","unit":"sats","value":100000000.0,"type":"crypto"}}}

my model with freezed package:

import 'package:freezed_annotation/freezed_annotation.dart';

part 'exchange_rates_response.freezed.dart';
part 'exchange_rates_response.g.dart';

/// {@macro ExchangeRates}
@Freezed(toJson: false, fromJson: false)
class ExchangeRatesResponse with _$ExchangeRatesResponse {
  /// {@macro ExchangeRates}
  factory ExchangeRatesResponse({List<RatesResponse>? rates}) =
      _ExchangeRatesResponse;

  /// {@macro ExchangeRates}
  factory ExchangeRatesResponse.fromJson(Map<String, dynamic> json) {
    var ratesMap = json['rates'] as Map<String, dynamic>;
    var ratesValues = ratesMap.values;
    List<RatesResponse> rates =
        List.from(ratesValues.map((e) => RatesResponse.fromJson(e)).toList());

    return ExchangeRatesResponse(rates: rates);
  }
}

/// {@macro ExchangeRates}
@Freezed(toJson: false)
class RatesResponse with _$RatesResponse {
  /// {@macro ExchangeRates}
  const factory RatesResponse({
    String? name,
    String? unit,
    double? value,
    String? type,
  }) = _RatesResponse;

  /// {@macro ExchangeRates}
  factory RatesResponse.fromJson(Map<String, dynamic> json) =>
      _$RatesResponseFromJson(json);
}

my model ExchangeRatesResponse works fine. but i want to know is there a way to use freezed package in ExchangeRatesResponse.fromJson function instead of manually convert it


Solution

  • Create an implementation of JsonConverter and annotate either the corresponding field or the containing class

    class ExchangeRateConverter implements JsonConverter<List<RatesResponse>?, Map<String, dynamic>> {
      const ExchangeRateConverter();
    
      @override
      List<RatesResponse>? fromJson(Map<String, dynamic> json) {
        var ratesValues = json.values;
        List<RatesResponse> rates =
            List.from(ratesValues.map((e) => RatesResponse.fromJson(e)).toList());
        return rates;
      }
    
      @override
      Map<String, dynamic> toJson(List<RatesResponse>? object) => {};
    }
    
    factory ExchangeRatesResponse({
        @ExchangeRateConverter() List<RatesResponse>? rates,
      }) = _ExchangeRatesResponse;