flutterdartinheritancesuper

inherit constructor and factory in flutter


I'm learning flutter and I'm trying to turn requests results into more convenient objects, so I created the basic schema of a response (which is not supposed to be instantiated anytime) :

class BaseModel {
  final String id;
  final DateTime createdAt;
  final DateTime updatedAt;
  final String databaseId;
  final String collectionId;

  BaseModel(
      {required this.id,
      required this.createdAt,
      required this.updatedAt,
      required this.databaseId,
      required this.collectionId});

  factory BaseModel.fromMap(Map<String, dynamic> map) {
    return BaseModel(
        id: map['\$id'].toString(),
        collectionId: map['\$collectionId'].toString(),
        createdAt: DateTime.tryParse(map['\$createdAt'].toString())!,
        updatedAt: DateTime.tryParse(map['\$updatedAt'].toString())!,
        databaseId: map['\$databaseId'].toString());
  }
}

I'd like to use this basis to create all the other objects I'll need, but I feel like I'm forced to write some useless code everytime I extend the class :

class ProfilePictureModel extends BaseModel {
  final String userId;
  final Uri pfp;

  ProfilePictureModel(
      {required super.id,
      required super.createdAt,
      required super.updatedAt,
      required super.databaseId,
      required super.collectionId,
      // everything above that has been written already in super class
      required this.userId,
      required this.pfp});

  factory ProfilePictureModel.fromMap(Map<String, dynamic> map) {
    return ProfilePictureModel(
      id: map['\$id'].toString(),
      collectionId: map['\$collectionId'].toString(),
      createdAt: DateTime.tryParse(map['\$createdAt'].toString())!,
      updatedAt: DateTime.tryParse(map['\$updatedAt'].toString())!,
      databaseId: map['\$databaseId'].toString(),
      // everything above that has been written already in super class
      userId: map['user_id'].toString(),
      pfp: Uri.dataFromString(map['pfp_url'].toString()),
    );
  }
}

So here's my question eventually : how can I take advantage of super constructor and factory in this situation ? I felt stuck with setting BaseModel abstract. Maybe am I going on the wrong way ? Thanks already peeps !


Solution

  • You can just directly use the BaseModel as an object instead of using it as a super class.

    class BaseModel {
      final String id;
      final DateTime? createdAt;
      final DateTime? updatedAt;
      final String databaseId;
      final String collectionId;
    
      BaseModel({
        required this.id,
        required this.createdAt,
        required this.updatedAt,
        required this.databaseId,
        required this.collectionId,
      });
    
      factory BaseModel.fromMap(Map<String, dynamic> map) {
        return BaseModel(
          id: map['id'] as String,
          createdAt: DateTime.tryParse(map['createdAt'].toString()),
          updatedAt: DateTime.tryParse(map['updatedAt'].toString()),
          databaseId: map['databaseId'] as String,
          collectionId: map['collectionId'] as String,
        );
      }
    }
    
    class ProfilePictureModel {
      final String userId;
      final String pfp;
      final BaseModel baseModel;
    
      ProfilePictureModel({
        required this.userId,
        required this.pfp,
        required this.baseModel,
      });
    
    
      factory ProfilePictureModel.fromMap(Map<String, dynamic> map) {
        return ProfilePictureModel(
          userId: map['userId'] as String,
          pfp: map['pfp'] as String,
          baseModel: BaseModel.fromMap(map['baseModel'] as Map<String, dynamic>),
        );
      }
    }
    
    

    Note: To create model classes in dart you can use extensions for VsCode or android studio.

    -> In VS code just add the "dart data class generator" extension.

    -> Create your class and define parameters.

    -> Hover over the class name and a bulb icon will appear, then tap on that bulb icon and then some options will visible (like: for data class, constructor, toJson()...).

    -> Then tap on "Generate data class".

    -> Your data class will be generated.

    or you can use: Quicktype