I have an array with countries with the following structure:
{
"code": "ZW",
"name": "Zimbabwe",
"zipPattern": "[\\s\\S]*",
"states": [
{
"name": "Bulawayo"
},
{
"name": "Harare"
},
{
"name": "Manicaland"
},
{
"name": "Mashonaland Central"
},
{
"name": "Mashonaland East"
},
{
"name": "Mashonaland West"
},
{
"name": "Masvingo"
},
{
"name": "Matabeleland North"
},
{
"name": "Matabeleland South"
},
{
"name": "Midlands"
}
]
}
I am trying to insert them into MongoDb
using MongoSkin
with the following code
var countries = require('./mongo/ready/Countries');
db.collection('countries').find().toArray(function (err, result) {
if (result.length === 0) {
for (var i = 0; i < countries.length; i++) {
var obj = countries[i];
var states = obj.states;
db.collection('countries').insert({
name: obj.name,
code: obj.code,
zipPattern: obj.zipPattern
}, function (error, countryResult) {
var id = countryResult[0]._id;
for (var j = 0; j < states.length; j++) {
var state = states[j];
db.collection('states').insert({
countryId: id,
name: state.name
}, function (stateError, stateResult) {
if (stateError) console.log(stateError);
console.log(stateResult);
});
}
});
}
}
});
but the code inserts the states of the last country in the array (Zimbabwe) for each country in the array instead of the correct states. How can I fix it?
Generally we don't use async query(insert) between sync loop(simple for loop). Its give us abnoramal results. Node provides async loop to overcome this.
First of all require async module for this.
var async = require('async');
Now you can use following code for insertion of countries and their respective states
async.each(countries, function(obj, callback) {
var states = obj.states;
db.collection('countries').insert({
name: obj.name,
code: obj.code,
zipPattern: obj.zipPattern
}, function(error, countryResult) {
if (error) {
callback(error);
} else {
var id = countryResult[0]._id;
async.each(states, function(state, callback) {
db.collection('states').insert({
countryId: id,
name: state.name
}, function(stateError, stateResult) {
if (stateError) {
callback(stateError);
} else {
callback();
}
});
});
callback();
}
}); }, function(err) {
if (err) {
// handle error here
} else {
// do stuff on completion of insertion
} });
Thanks