Reputation: 85
I am actually trying to save a new record in my mongodb databse.
company.save(function(err, company){
if (err)
//fail;
//success
})
But, before this action, i'd like to add tags to my company
My company schema
var companySchema = new mongoose.Schema({
name: String,
accro: String,
npa: String,
city: String,
country: String,
isverified : Boolean,
tags: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Tag' // réf. tagSchema
}
]
})
as you can see, tags is a ref so i'm checking if the tag already exists or not:
for (var i = 0; i < req.body.tags.length; i++) {
var currentTag = req.body.tags[i];
Tag.findOne({'label': currentTag }, function(err,t){
var tag_id = "";
if(err) res.send(err);
// if exist
if (t) {
console.log("#" + i + " currentTag existe");
t.use++;
t.save();
tag_id = t._id;
} else {
console.log("#" + i + " currentTag not existe");
var tag = new Tag();
tag.label = currentTag;
tag.save();
tag_id = tag._id;
}
company.tags.push(tag_id);
});
}
but as the mongoose findOne function has a callback, the loop just keeps "looping" and when the company.save()
is fired, no tags has been added to the company..
Need some help to get it asynchronous :) Thanks
Upvotes: 0
Views: 569
Reputation: 2922
You need not to find tags one by one. use $in operator like below:
Tag.find({'label': {$in: req.body.tags}},function(err,oldTags){
if(err) res.send(err);
var tag_id = '';
for(var i = 0; i < req.body.tags.length; i++){
for(var j = 0; j < oldTags.length; j++){
if(req.body.tags[i] == oldTags[j].label){
oldTags[j].use++;
oldTags[j].save(function(err, tag) {
company.tags.push(tag._id);
});
} else {
console.log("#" + i + " currentTag not existe");
var tag = new Tag();
tag.label = req.body.tags[i];
tag.save(function(err, newTag) {
company.tags.push(newTag._id);
});
}
}
}
// HERE SAVE YOUR COMPANY OBJECT
});
UPDATE
Tag.find({
'label': {
$in: req.body.tags
}
}, function(err, oldTags) {
if (err) res.send(err);
var tags_id = [];
var db_labels = [];
var db_ids = [];
var new_tags = [];
for (var i = 0; i < oldTags.length; i++) {
db_labels.push(oldTags[i].label);
db_ids.push(oldTags[i]._id);
}
for (var i = 0; i < req.body.tags.length; i++) {
var label = req.body.tags[i].trim().toUpperCase();
var tag_id = "";
if (db_labels.indexOf(label) == -1) {
//tag not found
//var tag = new Tag();
//tag.label = label;
new_tags.push({
label: label
})
// tag.save(function(err, newTag) {
// tags_id.push(newTag._id);
// });
} else {
//tag found
tags_id.push(db_ids[db_labels.indexOf(label)]);
}
}
Tag.collection.insert(new_tags, function(err, data) {
tags_id = tags_id.concat(data.insertedIds);
company.tags = tags_id;
company.save(function(err, company) {
if (err)
res.send(err);
res.json(company);
})
});
});
Upvotes: 1
Reputation: 85
Following @Sachin answer: got this:
Tag.find({'label': {$in: req.body.tags}},function(err,oldTags){
if(err) res.send(err);
var tags_id = [];
var db_labels = [];
var db_ids = [];
for (var i = 0; i < oldTags.length; i++) {
db_labels.push( oldTags[i].label );
db_ids.push( oldTags[i]._id );
}
for (var i = 0; i < req.body.tags.length; i++) {
var label = req.body.tags[i].trim().toUpperCase();
var tag_id = "";
if ( db_labels.indexOf(label) == -1) {
//tag not found
var tag = new Tag();
tag.label = label;
tag_id = tag._id;
tag.save();
} else {
//tag found
tag_id = db_ids[db_labels.indexOf(label)];
}
tags_id.push( tag_id )
}
company.tags = tags_id;
company.save(function(err, company){
if (err)
res.send(err);
res.json(company);
})
});
Upvotes: 0
Reputation: 10997
Pattern you are looking for is promise.all
var q = require('q');
var arr = [];
for (var i = 0; i < req.body.tags.length; i++) {
//check if tag exist and if not create
var promise = tag.save();
arr.add(promise)
}
q.all(arr).then(function(newArr) { //check what comes in newArr and set it in company tags
company.tags.push(newArr);
//save company
});
Upvotes: 1