Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Seeding Data for a StrongLoop App

DZone's Guide to

Seeding Data for a StrongLoop App

Automatically restarting a node.js application when a file changes speeds up development but means lots of restarts. This article shows how to re-seed data into a test application when using StrongLoop.

· Web Dev Zone
Free Resource

Add user login and MFA to your next project in minutes. Create a free Okta developer account, drop in one of our SDKs to your application and get back to building.

Please Read! A few hours after posting this, a member of the StrongLoop team pointed out an alternative that did exactly what I wanted to accomplish in about one second of typing. I still think the core of this blog entry makes sense as is so I’m not editing it, but see the note at the bottom!

This is just a quick post as a followup to something I mentioned in my post the other day on building a blog with Strongloop. I mentioned that while working on my application, I kept losing my temporary data as I was using the “In Memory” datasource that is the default persistence method for data. That’s not a bug—in memory means exactly that—in memory—and as I restarted the app (using nodemon), I had to re-enter fake data to test.

While it takes all of three minutes to connect your app to Mongo, if you don’t have Mongo (or MySQL, or a db in general), it would be nice to be able to stick with the simple RAM based system while prototyping.

One of the things I realized is that Strongloop will run a set of scripts inside the boot directory on startup. In theory, that could be used to set some seed data. Jordan Kasper (evangelist for StrongLoop, which sounds like a fun job, ahem) shared this script with me as an example:

https://github.com/strongloop-training/coffee-time/blob/master/server/boot/create-sample-model-data.js

var async = require('async');
var mysqlDatasourceName = 'mysql_dev';
var mongoDatasourceName = 'mongodb_dev';

module.exports = function(app) {
  //data sources
  var mongoDs = app.dataSources[mongoDatasourceName];
  var mysqlDs = app.dataSources[mysqlDatasourceName];
  //create all models
  async.parallel({
    reviewers: async.apply(createReviewers),
    coffeeShops: async.apply(createCoffeeShops),
  }, function(err, results) {
    if (err) throw err;
    createReviews(results.reviewers, results.coffeeShops, function(err) {
      if (err) throw err;
      console.log('> models created sucessfully');
    });
  });
  //create reviewers
  function createReviewers(cb) {
    mongoDs.automigrate('Reviewer', function(err) {
      if (err) return cb(err);
      var Reviewer = app.models.Reviewer;
      Reviewer.create([
        {email: 'foo@bar.com', password: 'foobar'},
        {email: 'john@doe.com', password: 'johndoe'},
        {email: 'jane@doe.com', password: 'janedoe'}
      ], cb);
    });
  }
  //create coffee shops
  function createCoffeeShops(cb) {
    mysqlDs.automigrate('CoffeeShop', function(err) {
      if (err) return cb(err);
      var CoffeeShop = app.models.CoffeeShop;
      var shops = [
        {name: 'Bel Cafe',openingHour:10, closingHour:18},
        {name: 'Three Bees Coffee House',openingHour:6, closingHour:15},
        {name: 'Caffe Artigiano',openingHour:17, closingHour:24},
      ];
      //add city if it's in the model
      if(CoffeeShop.definition.properties.hasOwnProperty('city')){
        var cities = ['Vancouver', 'San Mateo'];
        shops.forEach(function(shop, idx){
          shop.city = cities[idx%2];
        });
      }
      CoffeeShop.create(shops, cb);
    });
  }
  //create reviews
  function createReviews(reviewers, coffeeShops, cb) {
    mongoDs.automigrate('Review', function(err) {
      if (err) return cb(err);
      var Review = app.models.Review;
      var DAY_IN_MILLISECONDS = 1000 * 60 * 60 * 24;
      Review.create([
        {
          date: Date.now() - (DAY_IN_MILLISECONDS * 4),
          rating: 5,
          comments: 'A very good coffee shop.',
          publisherId: reviewers[0].id,
          coffeeShopId: coffeeShops[0].id,
        },
        {
          date: Date.now() - (DAY_IN_MILLISECONDS * 3),
          rating: 5,
          comments: 'Quite pleasant.',
          publisherId: reviewers[1].id,
          coffeeShopId: coffeeShops[0].id,
        },
        {
          date: Date.now() - (DAY_IN_MILLISECONDS * 2),
          rating: 4,
          comments: 'It was ok.',
          publisherId: reviewers[1].id,
          coffeeShopId: coffeeShops[1].id,
        },
        {
          date: Date.now() - (DAY_IN_MILLISECONDS),
          rating: 4,
          comments: 'I go here everyday.',
          publisherId: reviewers[2].id,
          coffeeShopId: coffeeShops[2].id,
        }
      ], cb);
    });
  }
};

I’m still new to Strongloop and Loopback in general, but this makes sense. My needs were far simpler, so here is a script I came up with (and again, Jordan helped me make it better) that just writes to a model in the in memory datasource.

var chalk = require('chalk');

console.log(chalk.magenta('Lets seed this app!'));

/*
This script is based on: 
https://github.com/strongloop-training/coffee-time/blob/master/server/boot/create-sample-model-data.js
*/

module.exports = function(app) {

//sample data
var data = [
{
title:'Content One', 
body:'Body One',
posted:new Date()
},
{
title:'Content Two', 
body:"Body Two",
posted:new Date()
},
{
title:'Content Three', 
body:'Body Three',
posted:new Date()
}
];

app.models.TestContent.create(data, function(err, records) {
if (err) { return console.log(chalk.red(err.message)); }
console.log(chalk.magenta('Done seeding data, '+records.length+' records created.'));
});

}

Pretty simple, and it works nicely.

Image title

But Wait — There’s More!

So, as I said up top, a few hours after posting this, Rand Mckinney from StrongLoop shared this link with me: Data persistence. In this doc, they mention that you can simply specify a JSON file for the datasource and the in memory data will persist to it. Like, seriously, exactly what I had wanted. Here is an example:

{                                                                                       
  "db": {
    "name": "db",
    "connector": "memory",
    "file": "mydata.json"
  }
}

Still—probably—a bad idea in production. But as I said, this would be incredibly useful when prototyping!

Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!

Topics:
strongloop ,nodejs ,test data

Published at DZone with permission of Raymond Camden, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}