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

@Default using non literal const (like Color) #149

Closed
bounty1342 opened this issue Apr 19, 2020 · 2 comments
Closed

@Default using non literal const (like Color) #149

bounty1342 opened this issue Apr 19, 2020 · 2 comments

Comments

@bounty1342
Copy link

bounty1342 commented Apr 19, 2020

Hi,

I run into an issue, trying to give a default value to a Color:

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

import '../../converter/color_converter.dart';

part 'themable.freezed.dart';
part 'themable.g.dart';

@freezed
abstract class Themable with _$Themable {
  const factory Themable({
    @Default(const Color.fromRGBO(0, 0, 0, 0))
    @ColorIntConv() Color backgroundColorRGB,
  }) = _Themable;

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

The json_converter is the following :

class ColorIntConv implements JsonConverter<Color, int> {
  const ColorIntConv();

  @override
  Color fromJson(int json) => Color(json);

  @override
  int toJson(Color object) => object.value;
}

This give the error :

Error with @JsonKey on backgroundColorRGB. defaultValue is Color, it must be a literal.

By removing the @default, it generates fine (themable.g.dart):

_$_Themable _$_$_ThemableFromJson(Map<String, dynamic> json) {
  return _$_Themable(
    backgroundColorRGB:
        const ColorIntConv().fromJson(json['backgroundColorRGB'] as int),
  );
}

Map<String, dynamic> _$_$_ThemableToJson(_$_Themable instance) =>
    <String, dynamic>{
      'backgroundColorRGB':
          const ColorIntConv().toJson(instance.backgroundColorRGB),
    };

So my take is that by handling those both json_converter et default annotation at the same time, it would be possible to handle Color or even custom type, assuming converter is provided.

What do you think ?

This could also help with : #82

@rrousselGit
Copy link
Owner

The problem is that jsonserializable doesn't like Color as default value

I can't so much for that. It's jsonserializable the problem, not freezed

@bounty1342
Copy link
Author

I thing I found a way to achieve it, not the best one, but it should work.

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

import '../../converter/color_converter.dart';

part 'themable.freezed.dart';
part 'themable.g.dart';

@freezed
abstract class Themable with _$Themable {
  const factory Themable({
    @ColorIntConv()
    @Default(ColorIntConv.defaultColor)
    @JsonKey()
        Color backgroundColorRGB,
  }) = _Themable;

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

@default(ColorIntConv.defaultColor) for Freezed.
@jsonkey() override so Freezed won't try to pass the default value.

Change the converter to handle default value if null :

import 'package:flutter/widgets.dart';
import 'package:json_annotation/json_annotation.dart';

class ColorIntConv implements JsonConverter<Color, int> {
  const ColorIntConv();
  static const Color defaultColor = Color.fromRGBO(0, 0, 0, 0);

  @override
  Color fromJson(int json) => json == null ? defaultColor : Color(json);

  @override
  int toJson(Color object) => object == null ? defaultColor : object.value;
}

No the most concise way but at least it works. Should works with #82 too.

I close it then, thanks for pointing me out to jsonserializable. 😃

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

2 participants