Thank you for the 0.7.0 update, the default values made my code a little bit simpler :)
One thing that I still have to work around are non-constant default values. My type has a String property called id that - if left empty - should have a random UUID value by default. I now work around this by adding a second factory method that redirects to the generated one without the id parameter.
It would be nice if the @Default annotation could also take in a lambda to generate the default value.
Dart only supports constant default values.
Are you looking for @late instead?
Ah, I see what you're speaking of.
But the syntax using @Default would be horrible as we can't use () => something inside decorators.
What about such syntax?
@freezed
abstract class SuperLate with _$SuperLate {
factory SuperLate([int value]) = _SuperLate;
@late
@override
int get value => super.value ?? Random().nextInt(9999);
}
Yes, that would be great! The late feature isn't enough because it doesn't allow the user to supply a custom value.
We'll probably need an alternate syntax for unions too:
@freezed
abstract class SuperLate with _$SuperLate {
factory SuperLate([@MyDefault() int value]) = _SuperLate;
factory SuperLate.emoty() = _SuperLate;
}
class MyDefault implements Default<T> {
const MyDefault();
T get defaultValue => Random().nextInt(9999);
}
Kinda verbose though.
It matched Json converter template (in a sense that is good).
Depending if this is an instance of Default() or JsonConverter(), will handle generation.
If this gets done, does this mean, we could have default non literals also ?
Hi @rrousselGit.
I write as
Ah, I see what you're speaking of.
But the syntax using@Defaultwould be horrible as we can't use() => somethinginside decorators.What about such syntax?
@freezed abstract class SuperLate with _$SuperLate { factory SuperLate([int value]) = _SuperLate; @late @override int get value => super.value ?? Random().nextInt(9999); }
but get error

This is not implemented. Just a thought
@rrousselGit Could this thought came to reality? I got into the same problem when I want to set empty list to a some field, but I can't get it generified in the @Default, and generator come broken when I tried to implement it writing block body, returning full-signatured constructor call with defaults written in this call. Like this:
factory RepositoryListDataModel({
@Default(false) bool fetchCompleted,
String query,
List<T> data
}) = {
return _RepositoryListDataModel<T>(query: query, data: data ?? <T>[]);
}
Another way to implement this would be to allow a function as Default's argument :
Other _defaultOther() => Other();
@freezed
abstract class Example with _$Example {
factory Example(@Default(_defaultOther) Other value) = _Example;
}
The problem is, people will most likely want to initialize some parameters based on other parameters
Yeah, probably the most common scenario.
But it may solve issues with json serializable :
For example :
@freezed
abstract class Other with _$Other {
const factory Other() = _Other;
factory Example.fromJson(Map<String, dynamic> json) => _$ExampleFromJson(json);
}
@freezed
abstract class Example with _$Example {
const factory Example(@Default(const Other()) Other value) = _Example;
factory Example.fromJson(Map<String, dynamic> json) => _$ExampleFromJson(json);
}
That produces this error :
Error with
@JsonKeyonvalue.defaultValueis_$_Other, it must be a literal.
I'm clueless on how to achieve this right now.
Another common use case that doesn't need other properties :
Example({
DateTime timestamp,
}) : timestamp = timestamp ?? DateTime.now().add(Duration(days: -30));
The nearest approach I found (though the value isn't initialized at instantiation, but at first read):
factory Example({
@JsonKey(name: 'timestamp') DateTime optionalTimestamp,
}) = _Example;
@late
DateTime get timestamp =>
optionalTimestamp ??
DateTime.now().add(Duration(days: -30));
Most helpful comment
Ah, I see what you're speaking of.
But the syntax using
@Defaultwould be horrible as we can't use() => somethinginside decorators.What about such syntax?