Home > Back-end >  How to use private constructor in json_serializable
How to use private constructor in json_serializable

Time:03-29

I'm using a private constructor in my class, but the code generation fails with

The class Foo has no default constructor.

I'm using latest json_serializable: version i.e. 6.1.5:

@JsonSerializable()
class Foo {
  final int count;
  Foo._(this.count);

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

What am I doing wrong?

CodePudding user response:

You can use @JsonSerializable(constructor: '_') which is introduced in the 4.2.0-dev of the JsonSerializable.

This will allow you to field to specify an alternative constructor to invoke when creating a fromJson helper.

For example:

import 'package:json_annotation/json_annotation.dart';

part 'foo.g.dart';

@JsonSerializable(constructor: '_')
class Foo {
  final int count;
  Foo._(this.count);

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

Now here, instead of using fromJson like this _$Foo._FromJson(json), use it as _$FooFromJson(json)

CodePudding user response:

Since you declared your constructor with _, there is no default constructor for your class. To fix your issue remove the _.

@JsonSerializable()
class Foo {
  final int count;
  const Foo(this.count);

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

CodePudding user response:

if you need to json_serializable: generate is for you, You have to define the default constructor. but you can mack this trick:

first do this and run build_runner:

@JsonSerializable()
class Foo {
  final int count;
  Foo(this.count);

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

then change it to this:

@JsonSerializable()
class Foo {
  final int count;
  Foo._(this.count);

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

and go to _.g.dart and mack call the Private constructor:

Foo _$FooFromJson(Map<String, dynamic> json) => Foo._(
      json['count'] as int,
    );

Map<String, dynamic> _$FooToJson(Foo instance) => <String, dynamic>{
      'count': instance.count,
    };
  • Related