Creating a Data Model

Let's create a Data Model for our note entry that conforms to the structure of our Data Source.

The BriteDatabase from the sqlbrite package allows us to create and fetch data from the SQL database in JSON format. Hence, we need to add a JSON serialization/deserialization feature to our NoteEntryModel.

In addition, we will also include a feature for mapping the Data Model into an Entity and vice-versa.

Under the note_app/modules/infrastructure/lib/data_sources/sqlbrite/ directory, create a file named note_entry_model.dart and paste the following code:

import 'package:domain/note/entities/note_entry.dart';
import 'package:infrastructure/data_sources/sqlbrite/sqlbrite_data_source.dart';
import 'package:json_annotation/json_annotation.dart';

part 'note_entry_model.g.dart';

/// {@template NoteEntryModel}
/// A model to represent a [NoteEntry] in the [SqlbriteDataSource].
/// {@endtemplate}
@JsonSerializable()
class NoteEntryModel {
  /// {@macro NoteEntryModel}
  const NoteEntryModel({
    required this.id,
    required this.title,
    required this.content,
    required this.updateTimestamp,
  });

  /// The unique identifier of the note entry.
  final String id;

  /// The title of the note entry.
  final String title;

  /// The content of the note entry.
  final String content;

  /// The timestamp of the last update of the note entry in milliseconds since
  /// epoch.
  final int updateTimestamp;

  /// A constructor to create a new [NoteEntryModel] from a [NoteEntry].
  factory NoteEntryModel.fromEntity(NoteEntry entity) => NoteEntryModel(
        id: entity.id,
        title: entity.title,
        content: entity.content,
        updateTimestamp: entity.updatedAt.millisecondsSinceEpoch,
      );

  /// Converts this [NoteEntryModel] to a [NoteEntry].
  NoteEntry toEntity() => NoteEntry(
        id: id,
        title: title,
        content: content,
        updatedAt: DateTime.fromMillisecondsSinceEpoch(updateTimestamp),
      );

  /// A constructor to create a new [NoteEntryModel] from a JSON object.
  factory NoteEntryModel.fromJson(Map<String, dynamic> json) =>
      _$NoteEntryModelFromJson(json);

  /// Converts this [NoteEntryModel] to a JSON object.
  Map<String, dynamic> toJson() => _$NoteEntryModelToJson(this);
}

Notice that the NoteEntryModel.updateTimestamp and NoteEntry.updatedAt serve the same purpose but have different names and data types?

This is a good example for highlighting the difference between an Entity and Data Model. That is, an Entity is entirely independent from a Data Source, whereas a Data Model is defined from a specific Data Source.

Once done, build the JSON serializable class for the NoteEntryModel using the build_runner:

cd modules/infrastructure
flutter pub run build_runner build --delete-conflicting-outputs

Tip: You can use a script to run the build_runner for multiple modules in one go.

Last updated