Loopback-next: After adding a new field, how to get the default value into existing documents?

Created on 7 Jan 2020  路  3Comments  路  Source: strongloop/loopback-next

I have added a new field to my model:

  @property({
    type: 'boolean',
    default: true,
  })
  isFoo: boolean;

Now, when I fetch an old existing document from the collection, I want to see it has the property isFoo: true. How can we achieve that?


Plan A: I fetch pre-existing instances of the model from MongoDB, but this new property is not present on the objects.

I was hoping to see isFoo: true on the objects I had fetched.


Plan B: I fetched a document, and saved it back:

const document = await myModelRepository.findOne({});
await myModelRepository.update(document!);

I was hoping doing this would set the default, storing isFoo: true in the DB.

But I actually saw isFoo: null stored in the DB. 馃槺 That seems like a violation of contract to me! (Given that Loopback's validation would reject such a document if I sent it to the API.)


Plan C: I tried to manually update the documents in the DB, using the defaults from new Model() but that object has no fields set at all, so I cannot see what the default value is supposed to be.


Plan D: This is what I have needed to do in practice (and also what derdeka mentions below). I run a migration script that checks for any documents with that field unset, and updates the value to true.

(This is basically Plan C except in Plan C I found I was unable to get the default value out of the model, so I have to hard-code the true in my migration script.)

This has a few disadvantages, not least of which needing to repeat the value true in a second place in the codebase. (Violates SSOT)


This was easy with Mongoose: Whenever documents were fetched, or written, any missing fields were populated with the default values.[1]

But as far as I can tell, Loopback 4 is only populating default values when I create a new document.

Is that the expected behaviour?

I built a fresh example project to ensure it wasn't just a problem with my project.


What am I asking for?

  • Discuss whether populating default values should be a feature when _reading_ and _writing_ entities, instead of only when _creating_. (This is what mongoose does, and it I have found it quite useful.)

  • Alternatively, please recommend how to achieve the population of new fields when needed (e.g. as a migration step).

  • Document the default property on the models page, when it is applied, and how to migrate old documents.


[1] Mongoose will skip population of defaults with sparse: true or validate: false options, useful when dealing with large numbers of records.

feature stale

All 3 comments

@joeytwiddle I have no idea how it works with mongodb, but in mysql and postgres I use database level defaults which are added when the migration process runs. After that they automatically return the default value.

This could potentially be a use-case for #487

This issue has been marked stale because it has not seen activity within six months. If you believe this to be in error, please contact one of the code owners, listed in the CODEOWNERS file at the top-level of this repository. This issue will be closed within 30 days of being stale.

Was this page helpful?
0 / 5 - 0 ratings