The documentation of freezed is telling that we should just use the sealed classes made available in dart 3. However: it does not explain how to use it, especially in combination with fromJson. So I'm a little stumped on how to do it with sealed classes instead of union types.
Given the following union;
import 'package:freezed_annotation/freezed_annotation.dart';
part 'example.freezed.dart';
part 'example.g.dart';
@freezed
sealed class Example with _$Example {
const factory Example.text({
required String text,
}) = _ExampleText;
const factory Example.nameLocation({
required String name,
required String location,
}) = _ExampleNameLocation;
factory Example.fromJson(
Map<String, dynamic> json,
) =>
_$ExampleFromJson(json);
}
void main() {
print(Example.fromJson({'runtimeType': 'text', 'text': 'Hello'}));
print(Example.fromJson({
'runtimeType': 'nameLocation',
'name': 'John',
'location': 'Amsterdam'
}));
}
I tried something like this - but that doesn't work. (The non-abstract class '_$ExampleTextImpl' is missing implementations for these members: _$Example.toJson)
import 'package:freezed_annotation/freezed_annotation.dart';
part 'example.freezed.dart';
part 'example.g.dart';
@freezed
sealed class Example with _$Example {
const factory Example() = _Example;
factory Example.fromJson(
Map<String, dynamic> json,
) =>
_$ExampleFromJson(json);
}
@freezed
class ExampleText extends Example with _$ExampleText {
const factory ExampleText({required String text}) = _ExampleText;
}
@freezed
class ExampleNameLocation extends Example with _$ExampleNameLocation {
const factory ExampleNameLocation({
required String name,
required String location,
}) = _ExampleNameLocation;
}
void main() {
print(Example.fromJson({'runtimeType': 'ExampleText', 'text': 'Hello'}));
print(Example.fromJson({
'runtimeType': 'ExampleNameLocation',
'name': 'John',
'location': 'Amsterdam'
}));
}
Looks like it's the same as before, except we would make the classes not private and freezed will generate the classes after the =
.
import 'package:freezed_annotation/freezed_annotation.dart';
part 'example.freezed.dart';
part 'example.g.dart';
@freezed
sealed class Example with _$Example {
const factory Example.text({
required String text,
}) = ExampleText;
const factory Example.nameLocation({
required String name,
required String location,
}) = ExampleNameLocation;
factory Example.fromJson(Map<String, dynamic> json) =>
_$ExampleFromJson(json);
}
void main() {
final example =
Example.fromJson({'runtimeType': 'text', 'text': 'Hello World!'});
final type = switch (example) {
ExampleText() => 'ExampleText',
ExampleNameLocation() => 'ExampleNameLocation',
};
print(type); // ExampleText
}
I do think this is a little unclear in the documentation, but I guess it's not that much different as before. Just don't use when.