Loopback: Creating a Seed Script

by Markus Spiske on Unsplash

Now that we have our API setup we need data to persist. Adding data to our tables manually is not efficient, and we need a way of quickly populating data for not only prototyping but also testing. Creating a Seed Script will solve this problem, by clearing and creating table data in less than 2s.

Existing data model

This article builds on two other articles that I have recently written about Loopback.js. The Github is linked at the bottom along with the other articles. This series is loosely coupled, so hopefully, you can jump right in. To the left is the current working API data model.

Setup

To get started creating out seed script the first thing we need to do is create two files in the ./server/scripts folder. These files can be called anything for the purpose of this article, mine will be called dummy-data.js and seed.js

Creating Data File

Before we seed data, we must have data to seed. This is where the dummy-data.js file comes in. Going through all models, create arrays of objects under the name of the model they correspond to. The name field of a model can be found in the .json file for that model.

For our example below module.exports.student matches "name":"student"

Export Name = Model Name

These arrays will be iterated in our script and each object will be used to create a row in our database.

For relational data, you need to manually add the foreign ids. Mysql ids increment from 0, which makes it predictable. This is critical in seeding valid relations.

I like to override the implicitly generate model properties for relations. This allows me to match up the property names I create with the foreign keys I enter.

For our example, the foreign key studentId in dummy-data.js must match the foreign key property name in your model(ie studentId).

Model and Dummy-Data foreign keys must match

Creating Seed Script

In the seeding process, there are two main steps: deleting existing data and creating new data. To do both of these operations I use the destroyAll and create methods that can be found on the model objects. Detail for those methods can be found here.

Imports

Imports I use for seeding script

Just noting here that you must import the server and grab the data source and models off of it.

Also, I am just using Chalk to make my command line more colorful. That is completely optional.

Deleting

For deleting data from our database I wrap the destroyAll method to provide some feedback on the console.

Delete Function

Essentially, all we are doing here is getting the model by name, running destroyAll on it, and calling the callback.

Creating

Similarly to deleting data, I just wrap the create method and provide feedback to the console.

Create function

Bringing it all together

Because there are constraints on our relationships we need to create the models in order of increasing relationships and delete them in order of decreasing relationships. Otherwise, we will run into conflicts where we are creating data with a relationship that can’t exist, or we are deleting data that is referenced elsewhere.

Model names in the two orders we need

In our example, this means creating (Students and Subjects) then (Lockers and Class) then (Enrollment and Teacher) and deleting in reverse order.

Database daigram

All of the create and destroy methods are async and instead of returning promises they currently take a callback function. I believe the loopback team is currently working to upgrade this. Until they finish this change and to avoid callback hell, I use the Async library. The Async library has a method called eachSeries. This method takes in a list of items, a function to call, and a callback to run when all of the elements are finished.

I call eachSeries twice. Once to loop through the model names and delete and then again to loop through the model names in reverse and create.

Create Node scripts

To ease in the refreshing of the data I like to create two scripts in the package.json.

Thus when you want to update your schema all you have to do is call npm run migrate and npm run seed

Conclusion

Now we have a fully working seed command. You can see example output below.

Paired with the migration command I have previously discussed, these two commands can make testing and prototyping with your API drastically more efficient.

Now to find out which dependency is using timers.enroll()

🤟Josh

Joshuawootonn.com

Github Repo

Previous articles in this series.

Loopback: Config Files

Loopback: Models and Relations

--

--

--

https://joshuawootonn.com

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Typescript game engine

XPath in Selenium: How to find any element accuratly in Selenium WebDriver

How to test your Socket.IO server using Postman

NodeJS : All about unit testing

What is ES6? Welcome to 21st Century

Async, Await Spark AR Scripting Guide For Beginners

NOTES: NativeScript + Angular

Node.js Weekly Update — 5 May, 2017

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Joshua Wootonn

Joshua Wootonn

https://joshuawootonn.com

More from Medium

Template Engine (Ejs vs Pug )

Meteor: using publish-subscribe pattern without MongoDB

All along when people asked me about how publish-subscribe works, I always used a great analogy to explain that: the radios. The radio station would be the publisher and those who were tuning their radios on this radio would be the subscribers.

Firebase user count per provider

Software Application Development Services