priyank
priyank

Reputation: 148

How to handle async request at client nodejs?

I am new to NodeJS. I am using NodeJS on server side. I am trying to make a simple REST based GET request which takes search parameter searchvar from user and returns the matching records found in a JSON array. My server code is as follows:

var express = require('express');
var app = express();
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var ObjectId = require('mongodb').ObjectID;
var url = 'mongodb://localhost:27017/mydb';

app.get('/search', function(req, res) {
  res.set({ 'content-type': 'application/json; charset=utf-8' });
  res.header("Content-Type", "application/json; charset=utf-8");
  res.charset = 'utf-8';

  var searchvar = req.query.searchvar;

  if(searchvar != null) {
    var recordsArray = new Array();
    console.log("searchvar :: " + searchvar );

    MongoClient.connect(url, function(err, db) {
      var cursor = db.collection('myCollections').find({"name": new RegExp(searchvar)});
      cursor.each(function(err, doc) {
        //assert.equal(err, null);
        if (doc != null) {
          var tempObject = {"name": doc.name, "cat": doc.cat};
          recordsArray.push(tempObject);
          console.dir(doc);
        } else {
          db.close();
        }
      });

      if(recordsArray.length > 0) {
        console.log("if........");
        res.json({"status": "SUCCESS", "message": "The request processed successfully.", "records":recordsArray});
      } else {
        console.log("else........");
        res.json({"status": "FAILURE", "message": "No records found corresponding to given search query."});
      }
    });
  } else {
    res.json({"status": "FAILURE", "message": "The searchvar is missing."});
  }

  //res.send('id: ' + req.query.id);
});

app.listen(3000);

When I call it with RESTClient in a browser with following URL:

http://localhost:3000/search?searchvar=aa

I get following response:

{"status": "FAILURE", "message": "No records found corresponding to given search query."}

It is an async call. I want to know the process in server using which i can return the response when the processing is done and handle this async response on client side. Thanks in advance.

Upvotes: 1

Views: 1033

Answers (3)

gnerkus
gnerkus

Reputation: 12037

The response occurs because the if check:

if(recordsArray.length > 0) {
    console.log("if........");

is executed before the callback passed to the cursor.each method has completed its processing. As a result, the array is empty.

Proposed solution
The cursor.forEach method takes a callback function that is executed asynchronously. This means you can access the results of the callback's execution only within the callback itself (except you return a Promise object). A fix would be:

cursor.forEach(function(doc) {
  if (doc != null) {
    var tempObject = {"name": doc.name, "cat": doc.cat};
    recordsArray.push(tempObject);
    console.dir(doc);
  }
}, function(err) {
  if(recordsArray.length > 0) {
    console.log("if........");
    res.json({"status": "SUCCESS", "message": "The request processed successfully.", "records":recordsArray});
  } else {
    console.log("else........");
    res.json({"status": "FAILURE", "message": "No records found corresponding to given search query."});
  }
  db.close();
});

Upvotes: 3

Perspectivus
Perspectivus

Reputation: 990

I think you're missing the callback parameter to the MongoClient Collection find() method. You should move your handling logic into the callback.

See these examples in the MongoDB documentation.

Your code would look something like this:

db.collection('myCollections').find({"name": new RegExp(searchvar)}).toArray(function(err, docs) {
    // iterate through docs; perform your logic
    db.close();
    res.json({...});
});

Upvotes: 1

Charlie
Charlie

Reputation: 2261

I think your best bet is to go through a Nodejs/MongoDB tutorial to understand how everything works. From a quick look at your code your response is not asynchronous. Any time the server responds right aways it's not async. Async is achieved on the server side when you implement something like Websockets or HTTP Callbacks.

I agree with Jim that the problem is probably in your client (please post the code if you still have questions). Generally a JS client achieves async by using callbacks or promises, but an async client does not require an async server. The reason it is common to make async client calls is so you don't lock up your GUI while waiting for a response from the server.

Upvotes: 0

Related Questions