dart_mappable icon indicating copy to clipboard operation
dart_mappable copied to clipboard

Multiple constructor

Open chungxon opened this issue 1 year ago • 4 comments

Hi, Thanks for the useful package!

I was just wondering if there was a way to make this package work with classes that have multiple constructors instead of the first available constructor or @MappableConstructor() annotaion. You can check out the similar feature in the Freezed package

chungxon avatar Feb 08 '25 18:02 chungxon

Not multiple constructors, but you can do polymorphism like this: https://pub.dev/documentation/dart_mappable/latest/topics/Polymorphism-topic.html

schultek avatar Feb 08 '25 20:02 schultek

Hi @schultek

Thanks for your solution! For some reason, I think Freezed is better for me in this case, but I like your package for my coding style. I switched from Freezed to dart_mappable somewhere and will try it more in other use cases in the future.

If you can support multiple constructors, it will be very useful.

You can close this ticket.

chungxon avatar Feb 10 '25 01:02 chungxon

I will keep it open as a feature request, but with low priority.

schultek avatar Feb 10 '25 07:02 schultek

Just want to add an code example because I have stumbled across this limitation as well. My code looked like this:

@MappableClass()
class Foo with FooMappable {
  final int? ident;

  final String? someData;
  final String? someDataOnlyForInsert;

  Foo.insert({
    required this.someData,
    required this.someDataOnlyForInsert
  }) : ident = null;

  Foo.update({
    required int this.ident,
    required this.someData,
  }) : someDataOnlyForInsert = null;
}

Basically, I have a DTO that represents an insert request or an update request. But in the encoded map the ident field is always missing.

MBulli avatar Mar 14 '25 13:03 MBulli

Hi @schultek never mind, I found a solution for this one. Anyone wants to implement multiple constructors like Freezed, you can refer to my example code below:

// Set the discriminator key to "type".
@MappableClass(discriminatorKey: 'type')
abstract class Animal with AnimalMappable {
  const Animal(this.name);

  // Factory constructors pointing to subclasses
  const factory Animal.nullAnimal(String name) = NullAnimal;

  const factory Animal.defaultAnimal(String name, String type) = DefaultAnimal;

  final String name;
}

// This sub-class will be chosen when the discriminator is null.
@MappableClass(discriminatorValue: null)
class NullAnimal extends Animal with NullAnimalMappable {
  const NullAnimal(super.name);
}

// This sub-class will be chosen on any unknown discriminator.
@MappableClass(discriminatorValue: MappableClass.useAsDefault)
class DefaultAnimal extends Animal with DefaultAnimalMappable {
  const DefaultAnimal(super.name, this.type);

  final String type;
}

chungxon avatar Jan 28 '26 03:01 chungxon

@schultek, I have created a PR #332 to add this example to the document. I would appreciate it if you could review it

You can close this issue. Thank you~

chungxon avatar Jan 28 '26 03:01 chungxon