user471221
user471221

Reputation:

Node.js + Mongoose... Control flow issue?

Just started to play around with node.js, have some past experience with JavaScript but very little in server-side.

I have the below code and the functionality that I'm looking for is too add a product to the collection using Mongoose, however, if a duplicate is found using 'name', then push the product as an embedded document to the duplicate, with only select information, such as product_ids, package info, etc. I'm assuming that the problem has to do with findOne not finding any duplicates on the first run. If I run it a second time, it does detect the duplicates, but by then it's too late. I'm not sure how to get findOne to run only after the previous 'save' occurred.

function insertProduct(data) {
    var product;
    Product.findOne({
        name: data.name
    }, function(err, doc) {
        if (err) throw err;
        if (!doc) {
            product = new Product({
                name: data.name
                //other product data
            });
            product.packages.push({
                //package data
            });
        }
        else if (doc) {
            doc.packages.push({
                //package data
            });
            product = doc;
        }
        product.save(function(err) {
            if (err) throw err;
            console.log('Added: ' + product.name);
        });
    });
}

request(url, function(error, response, body) {
   if (!error && response.statusCode === 200) {
      jsonResult = JSON.parse(body);
      jsonResult.result.forEach(insertProduct);
   }
});

I realize this has to be an issue with control flow, that I'm still trying to get a hold of. Your help is appreciated!

Upvotes: 3

Views: 961

Answers (1)

marko
marko

Reputation: 2104

Welcome to the world of non-blocking IO, and JavaScript closures :)

A simpler way around it is by separating the product creation and push the packages after the product is successfully created.

addProduct = function(name, next) {
  Product.findOne({name: name}, function(err, doc) {
    if(doc) {
      next(null, doc);
    }
    else {
      // create new product...
      var d = new Product({name: name});
      next(null, d);
    }
  });
});

// ... snipped

jsonResult.result.forEach(function(item) {
  addProduct(item.name, function(err, doc) {
    if(err == null) {
      doc.packages.push({
        // stuffs
      });
      doc.save();
    }
  });
});

Upvotes: 1

Related Questions