rethinkdb does not connect form grunt task

110 views Asked by At

I created a grunt task to create tables in a rethinkDB database. the issue that i am facing is that the connection is never established and no tables are created however if i do the same while serving a regular API endpoint everything works as expected.

below is an extract from the Gruntfile.js

'use strict';

var config = require(__dirname + '/config.js');
var r = require('rethinkdb');

module.exports = function (grunt) {
  grunt.registerTask('createDatabases', 'Task to create rethinkDB tables', function () {
r.connect({
  host: config.rethinkDB.host,
  port: config.rethinkDB.port
}, function (err, conn) {
  if (err) throw err;
  r.db(config.rethinkDB.dbName).tableCreate('tv_shows').run(conn, function (err, res) {
    if (err) throw err;
    console.log(res);
    r.table('tv_shows').insert({name: 'Star Trek TNG'}).run(conn, function (err, res) {
      if (err) throw err;
      console.log(res);
    });
  });
});
  });
};

Thanks in advance

1

There are 1 answers

1
Jorge Silva On BEST ANSWER

The problem is that your task is asynchronous, but you're treating it as an asynchronous task. Your task finishes and your process exists, but you still haven't created your table and executed your insert.

What you need to do is add one line right underneath registerTask that creates a done function. Then you can call this done function when your process is actually done. If you've ever used mocha, you might be familiar with this pattern.

/*jshint node:true */
'use strict';

var config = {
  rethinkDB: {
    host: 'localhost',
    port: 28015,
    dbName: 'test'
  }
};

var r = require('rethinkdb');

module.exports = function (grunt) {
  grunt.registerTask('default', 'Task to create rethinkDB tables', function () {

    // 1. Declare your `done` function 
    var done = this.async();

    return r.connect({
      host: config.rethinkDB.host,
      port: config.rethinkDB.port
    }, function (err, conn) {
      if (err) throw err;
      return r.db(config.rethinkDB.dbName).tableCreate('tv_shows').run(conn, function (err, res) {
        if (err) throw err;
        console.log(res);
        return r.table('tv_shows').insert({name: 'Star Trek TNG'}).run(conn, function (err, res) {
          if (err) throw err;
          console.log(res);

          // 2. Call your `done` function once everything is done
          done();

        });
      });
    });
  });
};

Your code does have one other bug. I imagine you'll run this multiple times and basically, you want to make sure that these table exist, but don't want it to throw an error if the table exists. RethinkDB, by default, throws an error if you create a table that already exists, so you should consider doing this:

      return r.db(config.rethinkDB.dbName).tableCreate('tv_shows').run(conn, function (err, res) {
        // Don't throw an error or consider doing handling the error
        // if (err) throw err;
        console.log(res);
        // ...

Promises

You might consider making this code a bit cleaner by using promises:

module.exports = function (grunt) {
  grunt.registerTask('default', 'Task to create rethinkDB tables', function () {
    var done = this.async();
    return r.connect({
      host: config.rethinkDB.host,
      port: config.rethinkDB.port
    })
    .then(function (conn) {
      return r.db(config.rethinkDB.dbName).tableCreate('tv_shows').run(conn)
        .catch(function () { })
        .then(function () {
          return r.table('tv_shows').insert({name: 'Star Trek TNG'}).run(conn);
        });
    })
    .then(done);
  });
};