webix-hub / webix-remote-js

Simple RPC for NodeJS and Webix UI
http://webix.com
5 stars 3 forks source link

Mongo DB Async callback wont return values #3

Open ghost opened 8 years ago

ghost commented 8 years ago
//This code works using Express.js with REST API 
// Create new record, write data to Mongo DB collection (dbCollection)
app.post('/api/tags', function(req, res){
    console.log('22222');
    console.log(req.body);
    dbCollection.insert(req.body, function(err, record){
      if (err) return res.send({ status:"error" });
    res.send({ newid:req.body._id });
  });
});

//This code does not work because of the callback for dbCollection.insert()
api.setMethod("add", function(a){
    dbCollection.insert(a, function(err, record){
        if (err) {
            return 'error';
          } else {
            return 'success';
        }   
});

Is it possible to use Synchronize to convert the dbCollection async to a sync method? see: https://coderwall.com/p/5okc9g/eliminating-callback-hell-in-node-js-with-synchronize or: http://alexeypetrushin.github.io/synchronize/docs/index.html

What other options are there to make Webix Remote work with async database callbacks?

ghost commented 8 years ago

One solution to this issue is to convert the asynchronous method to a synchronous method, as follows:

// Used to convert Async methods to Sync methods for RPC when using Webix Remote
var sync = require('synchronize');

// RPC (Remote Procedure Call) using Webix version 3.4 and Webix Remote
var rpcRemote = require("webix-remote");
var rpc = rpcRemote.server();

var express = require('express');
var app = express();

// Database compatible with Mongo
var dbEngine = require('tingodb')();
var db = new dbEngine.Db(pathDatabase, {});
var dbCollection = db.collection("test.json");

// Convert Async code to Sync code for Webix Remote when using a DB (Tingo or MongoDb)
sync(dbCollection, 'find');
sync(dbCollection, 'insert');
sync(dbCollection, 'update');
sync(dbCollection, 'remove');

// Allows Express app to use synchronize (sync.fiber) to convert async methods to sync methods inside of Express callbacks
app.use(function(req, res, next){
  sync.fiber(next)
})

// Find a database record for the Tag
rpc.setMethod("dbFind", function(selectedID){
    // error handling since we dont have the callback to handle the error
    try {
        // Convert the Async database call to a Sync call using Fibers
        var result = sync.await(dbSavedData.find({id: selectedID}).toArray(sync.defer()));
        // the result is an array of a JSON object and thus the reason for results[0]
        return result[0];
    } catch(err) {
        console.error(err);
    }
});