Mobile Dev

Flutter json_serializable fromJson Error: Nested Classes Fix

Resolve 'The method 'fromJson' isn't defined for SubOne/SubTwo' in Flutter json_serializable nested classes. Add factory delegates with explicitToJson for self-referential lists. Full code, build_runner steps, and best practices.

1 answer 1 view

Flutter json_serializable with nested classes: 'The method ‘fromJson’ isn’t defined for the type ‘SubOne’ or ‘SubTwo’

Using Flutter on Windows (latest version), I created these nested classes with @JsonSerializable(explicitToJson: true):

dart
import 'package:json_annotation/json_annotation.dart';
part 'test.g.dart';

@JsonSerializable(explicitToJson: true)
class Test {
 String name;
 SubOne subOne;

 Test(this.name, this.subOne);
}

@JsonSerializable(explicitToJson: true)
class SubOne {
 String name = '';
 List<SubOne> subOnes = [];
 List<SubTwo> subTwos = [];
}

@JsonSerializable(explicitToJson: true)
class SubTwo {
 String name = '';
}

After running dart run build_runner build, test.g.dart shows these errors:

The method 'fromJson' isn't defined for the type 'SubOne'.
The method 'fromJson' isn't defined for the type 'SubTwo'.

What causes this and how to resolve it?

Flutter json_serializable nested classes fail with “fromJson isn’t defined” errors because code generation creates helper functions like _$SubOneFromJson, but doesn’t automatically add fromJson factory constructors to your classes—especially for nested or self-referential ones like List<SubOne>. The @JsonSerializable(explicitToJson: true) flag only ensures nested toJson calls in serialization, not deserialization factories. Fix it by manually adding factory fromJson and toJson delegates to every class (Test, SubOne, SubTwo), then rerun dart run build_runner build --delete-conflicting-outputs.


Contents


Understanding the ‘fromJson isn’t defined’ Error in Flutter json_serializable

Ever hit that wall where your test.g.dart file compiles but screams “The method ‘fromJson’ isn’t defined for the type ‘SubOne’”? You’re not alone—this pops up constantly with Flutter json_serializable nested classes, especially on Windows with the latest Dart/Flutter setup. The generated code tries to deserialize your Test object by calling SubOne.fromJson(json['subOne']), but SubOne lacks that factory method. Same deal for SubTwo.

It happens because json_serializable generates low-level helpers (_$SubOneFromJson, _$SubOneToJson) in the .g.dart part file. But for the top-level Test.fromJson to work, it needs to invoke fromJson on nested types during deserialization. Without them? Boom—compile errors.

Quick peek at your generated test.g.dart snippet (paraphrased):

dart
Test _$TestFromJson(Map<String, dynamic> json) {
 return Test(
 json['name'] as String,
 SubOne.fromJson(json['subOne'] as Map<String, dynamic>), // ❌ Missing!
 );
}

Self-referential lists like List<SubOne> in SubOne make it worse—they demand factories everywhere in the chain. Stack Overflow threads echo this exact pain point, with devs scratching heads over why annotations alone don’t cut it.


Why @JsonSerializable(explicitToJson: true) Doesn’t Fix Nested Classes

You added @JsonSerializable(explicitToJson: true) thinking it’d handle nested json_serializable classes automatically. Smart move, but here’s the kicker: it doesn’t touch deserialization at all.

Per the json_annotation docs, explicitToJson: true only forces toJson methods on nested objects to call their explicit serializers instead of assuming Map<String, dynamic>. Great for serialization output, like ensuring subOne.toJson() serializes its own subOnes list properly.

But fromJson? Crickets. No factory gets created unless you tell the generator explicitly—and even then, nested classes need their own. Your SubOne with List<SubTwo> subTwos = [] looks innocent, but without SubTwo.fromJson, the chain breaks.

Frustrating, right? Especially since Flutter’s official JSON serialization guide shows similar examples failing without manual intervention.


Root Cause: Missing Factory Constructors in Nested and Self-Referential Classes

Dig deeper, and it’s clear: json_serializable shines for flat objects but stumbles on hierarchies. The package documentation spells it out—code gen produces _$ClassFromJson and _$ClassToJson helpers, but your class must delegate to them via:

dart
factory Class.fromJson(Map<String, dynamic> json) => _$ClassFromJson(json);
Map<String, dynamic> toJson() => _$ClassToJson(this);

Why skip this for nested classes? The generator assumes you’ll add them manually for complex cases like yours. Self-referential List<SubOne> subOnes = []? Fully supported once factories exist on SubOne itself. Without, infinite recursion fears are moot because it won’t even compile.

In your setup:

  • Test.fromJson calls SubOne.fromJson → missing.
  • SubOne.fromJson would need to call SubOne.fromJson (for list items) and SubTwo.fromJson → both missing.

Windows quirks? Nah, it’s cross-platform—build_runner just enforces type safety strictly.


Step-by-Step Fix: Adding fromJson and toJson Delegates

Ready to fix Flutter json_serializable fromJson errors? Add the delegates to all three classes. Keep your annotations and constructors. Here’s the complete corrected code for test.dart:

dart
import 'package:json_annotation/json_annotation.dart';
part 'test.g.dart';

@JsonSerializable(explicitToJson: true)
class Test {
 String name;
 SubOne subOne;

 Test(this.name, this.subOne);

 factory Test.fromJson(Map<String, dynamic> json) => _$TestFromJson(json);
 Map<String, dynamic> toJson() => _$TestToJson(this);
}

@JsonSerializable(explicitToJson: true)
class SubOne {
 String name = '';
 List<SubOne> subOnes = [];
 List<SubTwo> subTwos = [];

 factory SubOne.fromJson(Map<String, dynamic> json) => _$SubOneFromJson(json);
 Map<String, dynamic> toJson() => _$SubOneToJson(this);
}

@JsonSerializable(explicitToJson: true)
class SubTwo {
 String name = '';

 factory SubTwo.fromJson(Map<String, dynamic> json) => _$SubTwoFromJson(json);
 Map<String, dynamic> toJson() => _$SubTwoToJson(this);
}

Boom. Now Test.fromJson deserializes subOne, which handles its lists by calling SubOne.fromJson and SubTwo.fromJson recursively—but safely, since lists terminate.

Test it quick:

dart
import 'dart:convert';

void main() {
 final jsonString = '''
 {
 "name": "Root",
 "subOne": {
 "name": "Sub One",
 "subOnes": [{"name": "Nested SubOne"}],
 "subTwos": [{"name": "A SubTwo"}]
 }
 }
 ''';

 final test = Test.fromJson(jsonDecode(jsonString));
 print(test.subOne.name); // "Sub One"
 print(jsonEncode(test.toJson())); // Roundtrip works!
}

The package example uses this exact pattern. Self-referential lists? No sweat—generates properly.


Running build_runner and Troubleshooting

Delete old junk first: dart run build_runner clean, then:

dart pub get
dart run build_runner build --delete-conflicting-outputs

On Windows (Flutter 3.x+ as of 2026), this spits out clean test.g.dart with no errors. Verify: flutter analyze should pass.

Common gotchas:

  • Single part file: All classes in one .dart sharing part 'test.g.dart';—works fine.
  • Lists fail? Ensure field types match (e.g., List<SubOne>.from(json['subOnes'].map((x) => SubOne.fromJson(x))) gets generated).
  • Infinite recursion? Won’t happen; generator handles cycles via explicitToJson.
  • Still broken? Check pubspec.yaml: json_annotation: ^4.9.0, json_serializable: ^6.8.0, build_runner: ^2.4.12. Bump if outdated.

If errors linger, nuke build/ and .dart_tool/ folders. SO confirms this wipes 90% of issues.


Alternatives and Best Practices for json_serializable

Manual factories too tedious? Try createFactory: true in @JsonSerializable()—auto-adds fromJson (but watch for cycles). Or createToJson: true for symmetry.

For huge nests, consider freezed package: @freezed with json_serializable mixin—generates everything automatically, including unions.

Best practices:

  • Annotate every class in the graph.
  • Use fieldRename: FieldRename.snake for API JSON.
  • build.yaml for config: exclude fields, custom converters.
  • Test roundtrips always: `expect(original.toJson(), json).

The changelog notes ongoing improvements, but delegates remain the gold standard for nested classes.


Sources

  1. json_serializable — Official documentation on code generation, factory delegates, and nested support: https://pub.dev/packages/json_serializable
  2. Flutter JSON and serialization — Official guide with nested class examples and fromJson requirements: https://docs.flutter.dev/data-and-backend/serialization/json
  3. JsonSerializable class — Annotation details on explicitToJson behavior and limitations: https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable-class.html
  4. json_serializable example — Package example showing fromJson/toJson delegate pattern: https://pub.dev/packages/json_serializable/example
  5. The method ‘fromJson’ isn’t defined — Stack Overflow discussion matching exact error: https://stackoverflow.com/questions/66906825/the-method-fromjson-isnt-defined-for-the-type-type

Conclusion

Flutter json_serializable nested classes errors like “fromJson isn’t defined” vanish once you add factory delegates to every class in your hierarchy—simple, reliable, and endorsed by official docs. Self-referential lists handle themselves post-fix. Rerun build_runner, test your roundtrips, and you’re golden. Skip the guesswork; this pattern scales to complex apps without hacks.

Authors
Verified by moderation
Flutter json_serializable fromJson Error: Nested Classes Fix