Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SubclassFromJson not defined for Superclass #4

Open
burhankhanzada opened this issue Jan 4, 2024 · 2 comments
Open

SubclassFromJson not defined for Superclass #4

burhankhanzada opened this issue Jan 4, 2024 · 2 comments
Labels
enhancement New feature or request

Comments

@burhankhanzada
Copy link

I haved Human as superclass and Student as subclass and defined Student as explicitSubTypes to Human morphy annotation options with generateJson to true but getting error for _$StudentFromJson

The method '_$StudentFromJson' isn't defined for the type 'Human'.
Try correcting the name to the name of an existing method, or defining a method named '_$StudentFromJson'.dart[undefined_method](https://dart.dev/diagnostics/undefined_method)

human.dart

import 'package:morphy_annotation/morphy_annotation.dart';
import 'package:morphy_test/student.dart';

part 'human.g.dart';
part 'human.morphy.dart';

@Morphy(generateJson: true, explicitSubTypes: [$Student])
abstract class $Human {
  String get name;
  int get age;
}

student.dart

import 'package:morphy_annotation/morphy_annotation.dart';
import 'package:morphy_test/human.dart';

part 'student.g.dart';
part 'student.morphy.dart';

@Morphy(generateJson: true)
abstract class $Student implements $Human {
  String get rollNo;
}

human.morphy.dart

// ignore_for_file: UNNECESSARY_CAST
// ignore_for_file: unused_element

part of 'human.dart';

// **************************************************************************
// Generator: MorphyGenerator<Morphy>
// **************************************************************************

///

@JsonSerializable(
  explicitToJson: true,
)
class Human extends $Human {
  final String name;
  final int age;

  ///
  Human({
    required this.name,
    required this.age,
  });
  Human._({
    required this.name,
    required this.age,
  });
  String toString() => "(Human-name:${name.toString()}|age:${age.toString()})";
  int get hashCode => hashObjects([name.hashCode, age.hashCode]);
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Human &&
          runtimeType == other.runtimeType &&
          name == other.name &&
          age == other.age;
  Human copyWith_Human({
    String Function()? name,
    int Function()? age,
  }) {
    return Human._(
      name: name == null ? this.name as String : name() as String,
      age: age == null ? this.age as int : age() as int,
    );
  }

//$Student|[]|[rollNo:String:$Student, name:String:$Human, age:int:$Human]$Human|[]|[name:String:null, age:int:null]
//$Student|[]|[rollNo:String:$Student, name:String:$Human, age:int:$Human]
  factory Human.fromJson(Map<String, dynamic> json) {
    if (json['_className_'] == "Student") {
      return _$StudentFromJson(
        json,
      );
    } else if (json['_className_'] == "Human") {
      return _$HumanFromJson(
        json,
      );
    } else {
      throw UnsupportedError(
          "The _className_ '${json['_className_']}' is not supported by the Human.fromJson constructor.");
    }
  }

  // ignore: unused_field
  Map<Type, Object? Function(Never)> _fns = {};

  Map<String, dynamic> toJson_2([Map<Type, Object? Function(Never)>? fns]) {
    this._fns = fns ?? {};
    return toJson();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = _$HumanToJson(
      this,
    );
    // Adding custom key-value pair
    data['_className_'] = 'Human';

    return data;
  }
}

extension $Human_changeTo_E on $Human {
  Human changeTo_Human({
    String Function()? name,
    int Function()? age,
  }) {
    return Human._(
      name: name == null ? this.name as String : name() as String,
      age: age == null ? this.age as int : age() as int,
    );
  }

  Student changeTo_Student({
    required String rollNo,
    String Function()? name,
    int Function()? age,
  }) {
    return Student._(
      rollNo: rollNo as String,
      name: name == null ? this.name as String : name() as String,
      age: age == null ? this.age as int : age() as int,
    );
  }
}

enum Human$ { name, age }

student.morpgy.dart

// ignore_for_file: UNNECESSARY_CAST
// ignore_for_file: unused_element

part of 'student.dart';

// **************************************************************************
// Generator: MorphyGenerator<Morphy>
// **************************************************************************

///
///implements [$Human]
///

///

@JsonSerializable(
  explicitToJson: true,
)
class Student extends $Student implements Human {
  final String name;
  final int age;
  final String rollNo;

  ///
  ///implements [$Human]
  ///

  ///
  Student({
    required this.name,
    required this.age,
    required this.rollNo,
  });
  Student._({
    required this.name,
    required this.age,
    required this.rollNo,
  });
  String toString() =>
      "(Student-name:${name.toString()}|age:${age.toString()}|rollNo:${rollNo.toString()})";
  int get hashCode =>
      hashObjects([name.hashCode, age.hashCode, rollNo.hashCode]);
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Student &&
          runtimeType == other.runtimeType &&
          name == other.name &&
          age == other.age &&
          rollNo == other.rollNo;
  Student copyWith_Human({
    String Function()? name,
    int Function()? age,
  }) {
    return Student._(
      name: name == null ? this.name as String : name() as String,
      age: age == null ? this.age as int : age() as int,
      rollNo: (this as Student).rollNo,
    );
  }

  Student copyWith_Student({
    String Function()? name,
    int Function()? age,
    String Function()? rollNo,
  }) {
    return Student._(
      name: name == null ? this.name as String : name() as String,
      age: age == null ? this.age as int : age() as int,
      rollNo: rollNo == null ? this.rollNo as String : rollNo() as String,
    );
  }

//$Human|[]|[name:String:$Human, age:int:$Human]$Student|[]|[name:String:null, age:int:null, rollNo:String:null]
//
  factory Student.fromJson(Map<String, dynamic> json) {
    if (json['_className_'] == "Student") {
      return _$StudentFromJson(
        json,
      );
    } else {
      throw UnsupportedError(
          "The _className_ '${json['_className_']}' is not supported by the Student.fromJson constructor.");
    }
  }

  // ignore: unused_field
  Map<Type, Object? Function(Never)> _fns = {};

  Map<String, dynamic> toJson_2([Map<Type, Object? Function(Never)>? fns]) {
    this._fns = fns ?? {};
    return toJson();
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = _$StudentToJson(
      this,
    );
    // Adding custom key-value pair
    data['_className_'] = 'Student';

    return data;
  }
}

extension $Student_changeTo_E on $Student {
  Student changeTo_Student({
    String Function()? name,
    int Function()? age,
    String Function()? rollNo,
  }) {
    return Student._(
      name: name == null ? this.name as String : name() as String,
      age: age == null ? this.age as int : age() as int,
      rollNo: rollNo == null ? this.rollNo as String : rollNo() as String,
    );
  }
}

enum Student$ { name, age, rollNo }

human.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'human.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Human _$HumanFromJson(Map<String, dynamic> json) => Human(
      name: json['name'] as String,
      age: json['age'] as int,
    );

Map<String, dynamic> _$HumanToJson(Human instance) => <String, dynamic>{
      'name': instance.name,
      'age': instance.age,
    };

student.g.dart

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'student.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

Student _$StudentFromJson(Map<String, dynamic> json) => Student(
      name: json['name'] as String,
      age: json['age'] as int,
      rollNo: json['rollNo'] as String,
    );

Map<String, dynamic> _$StudentToJson(Student instance) => <String, dynamic>{
      'name': instance.name,
      'age': instance.age,
      'rollNo': instance.rollNo,
    };
@burhankhanzada burhankhanzada changed the title SubclassFromJson not defined in Superclass SubclassFromJson not defined for Superclass Jan 4, 2024
@burhankhanzada
Copy link
Author

burhankhanzada commented Jan 4, 2024

after cloning the repo and running the 9 Change To test in example/readme_test.dart your test passes while i have done the same thing the difference is you defined both Pet = superclass, Cat = subclass in same file at readme_test.dart while i defined each class in its own file may be this causing issue and we are not importing subclass.g.dart file in our superclass.morphy.dart

@atreeon
Copy link
Owner

atreeon commented Jan 5, 2024

Hi @burhankhanzada thanks for trying out Morphy. Yes, if you use the explicitSubtypes, then you must create the classes in the same file. Would that fix the problem for you?

I would like to at some point look at a way of getting it to work without that. I'll update the readme, it does say same file somewhere in there but it should be more obvious.

Perhaps I should run a check and show a warning at least when we build our code.

@atreeon atreeon added the enhancement New feature or request label Jan 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants