LoopBack Quick Tip: Seeding Database using Life Cycle Observer

Diana Lau
Diana Lau
May 17 · 3 min read

The life cycle support is recently introduced in LoopBack 4, as mentioned in the April 2019 milestone blog. You can read the details in https://loopback.io/doc/en/lb4/Life-cycle.html. In this quick tip article, I’m going to show you how you can seed the database using this newly added feature.


In the Database Migration documentation, it mentions how to seed the database as part of the database migration script. As an alternative, you can make use of the life cycle observer to do that. Let’s take a look.

Create a Life Cycle Observer

At the root of your LoopBack application, run the life cycle observer generator command to generate the life cycle observer.

$ lb4 observer
? Observer name: AddData
? Observer group: AddDataGroup
create src/observers/add-data.observer.ts
update src/observers/index.ts
Observer AddData was created in src/observers/

Add Data Upon start()

Looking at the AddDataObserver , there are 2 generated methods: start() and stop(). We are going to add some data during the start of the application by calling Repository.create().

In my example, I have a SalesRepository that is associated with the Sales model. First, I need to get the SalesRepository in the AddDataObserver by adding the following constructor:

constructor(@repository('SalesRepository') private salesRepo: SalesRepository,) {}

Make sure you add the required import statements:

//import the repository decorator
import {repository} from '@loopback/repository';
//import the Sales and SalesRepository in my LB app
import {SalesRepository} from '../repositories';
import {Sales} from '../models';

In the start() method, call salesRepo.create() to add data to the database.

async start(): Promise<void> {
//create an instance of Sales to be inserted into the database
let salesData = new Sales({
description: 'this is a sample data',
date: '2019-01-01',
country: 'Canada',
total: 100,
});
this.salesRepo.create(salesData);
}

Generate Random Values

Now that we have successfully added one instance to the database, let’s generate some random values for the next 100 instances.

Generate a random number

Math.floor(Math.random() * MAX_VALUE);

Generate a random string

I found a good solution from this Stack Overflow post: https://stackoverflow.com/questions/1349404/generate-random-string-characters-in-javascript.

Math.random().toString(36).substring(MAX_TEXT_LENGTH);

Generate a random date

If you want to generate a random date within a date range, this gist https://gist.github.com/miguelmota/5b67e03845d840c949c4 would be useful for you.

function randomDate(start, end) {  
return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
}

Putting This Together

As a conclusion, here is what my Observer looks like. I’ve added one more check to make sure not to add any data if the database is not empty.

export class AddDataObserver implements LifeCycleObserver {
//get the "SaelsRepository" using the @repository decorator
constructor(
@repository('SalesRepository')
private salesRepo: SalesRepository,
) {}
/**
* This method will be invoked when the application starts
*/
async start(): Promise<void> {
// Add your logic for start// If there is data in the database, no need to add more
let count = (await this.salesRepo.count()).count;
if (count !== 0) return;
// Generate 100 instances of "Sales"
let rCountry: number = 0;
let rTotal: number = 0;
let rDesc: string = '';
let salesData: Sales;
for (let i = 0; i < 100; i++) { //generate random number for country
//I have an array of country names (size = 5) defined somewhere
rCountry = Math.floor(Math.random() * 5);
//generate random number for total
//between 0 and 1000
rTotal = Math.floor(Math.random() * 1000);
//generate random characters for description
//max length for description is 6
rDesc = Math.random().toString(36).substring(7);
salesData = new Sales({
description: rDesc,
date: this.randomDate().toDateString(),
country: COUNTRIES[rCountry],
total: rTotal,
});
this.salesRepo.create(salesData);}}//Generate a random date which is between 2018-01-01 and today
randomDate(): Date {
let minDate: Date = new Date(2018, 0, 1);
let maxDate: Date = new Date();
return new Date(
minDate.getTime() +
Math.random() * (maxDate.getTime() - minDate.getTime()),
);
}
...}

EDIT (2019/07/10): @dougal (github handle) mentioned that there’s a package called faker that can be used to generate random data as well. Thanks for the info!

References

LoopBack

LoopBack — The Node.js API Framework

Diana Lau

Written by

Diana Lau

loopback.io development. Words are my own.

LoopBack

LoopBack

LoopBack — The Node.js API Framework

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade