Dart what is the best way to create model with nullable field

Viewed 459

let's say I have the user model, I know all fields, id, name, createdAt, and updatedAt from database are not null, but when I want to add new user, id, cratedAt, and updatedAt are null because they will be inserted on database.

Then, my question is what is the best approach to handle this kind of typical case?

1. creating the user model with nullable fields.

class User {
  final String? id;
  final String name;
  final DateTime? createdAt;
  final DateTime? updatedAt;
  ...
}

This maybe the most typical approach, but I have to use ! or check null all the time and feel not good.

2. creating new user model for adding data other than existing one which has no nullable fields.

class User {
  final String id;
  final String name;
  final DateTime createdAt;
  final DateTime updatedAt;
...

}

class NewUser {
  final String? id;
  final String name;
  final DateTime? createdAt;
  final DateTime? updatedAt;
...

}

This could work on very small size but error prone.

3. generate fields, id, createdAt, and updatedAt on the client side, and use non nullable value on all fields

class User {
  final String id;
  final String name;
  final DateTime createdAt;
  final DateTime updatedAt;
...

}

This could work too, but generating id or timestamp on the client side is not good approach.

4. do you have any other recommendation?

I understand there is no silver bullet, and it depends on the situation or preference. I just want to learn the typical approach.

I would appreciate any advice even on the different langs, like java, swift, or kotlin.

1 Answers

My suggestion would be to use a private nullable field for the fields that can be null, and then a getter for that field that asserts that the private field is not null. So:

class User {
  final String? _id;
  final String name;
  ...
  
  String get id {
    assert(_id != null);
    return _id;
  }

  void set id(String value) => _id = value;

}

That way, you can use user.id just like you would any other field (like name), but you will get thrown an exception if you use it before it has been set, so you'll have to make sure not to read the field before the database has set the field. You will therefore want to set the field immediately after the database has generated the id. Same logic of course for the createdAt and updatedAt fields.

For convenience, you can add a getter on User that checks if all database-generated fields have been set, e.g.:

bool get databaseFieldsSet => _id != null && _createdAt != null && _updatedAt != null
Related