Reputation: 477
I am new to Node.js and Mongoose and need some help. So I first create an array called beerObjects. Then I make a request to breweryDB and store info in this array.
request(options, function (error, response, body) {
if (error) throw new Error(error);
obj = JSON.parse(body);
data = obj['data'];
for(i = 0; i < data.length; i++) {
var newBeer = new Beer();
newBeer.id = data[i]['id'];
newBeer.name = data[i]['name'];
newBeer.description = data[i]['description'];
newBeer.abv = data[i]['abv'];
if (data[i].hasOwnProperty('labels')) {
newBeer.image = data[i]['labels']['large'];
}
beerObjects.push(newBeer);
console.log(beerObjects[i].name);
}
addBeersToDatabase(beerObjects);
});
I have another function that will take this array and store the info in my mongo database.
function addBeersToDatabase(beerObjects) {
console.log(beerObjects.length);
for (i = 0; i < beerObjects.length; i++) {
console.log(beerObjects[i].id);
// check if beer is already in database
Beer.count({id: beerObjects[i].id}, function(err, count){
if (err) {
handleError(err);
}
if (count == 0) {
// add new beer to database
var newBeer = new Beer();
newBeer.id = beerObjects[i].id;
newBeer.name = beerObjects[i].name;
newBeer.description = beerObjects[i].description;
newBeer.abv = beerObjects[i].abv;
newBeer.image = beerObjects[i].image;
newBeer.save(function(err) {
if (err) {
throw err;
}
});
}
else {
// beer is already in database
}
});
}
}
In the beginning of the addBeerToDatabase() function, beerObject is defined and the console.log() statements output the correct information. But inside the Mongoose function Beer.count(), I get this error message.
newBeer.id = beerObjects[i].id;
TypeError: Cannot read property 'id' of undefined
This 'id' is the id of beerObjects[i], not newBeer. How do I correctly pass beerObjects to the mongoose function and use it in that function?
EDIT:
function addBeersToDatabase(beerObjects) {
for (i = 0; i < beerObjects.length; i++) {
console.log(beerObjects[i].beerId);
var currentBeer = beerObjects[i];
// check if beer is already in database
Beer.findOne({'beerId': currentBeer.beerId}, function(err, beer){
if (err) {
handleError(err);
}
if (beer) {
// beer is already in database
}
else {
// add new beer to database
console.log(currentBeer.name);
saveNewBeer(currentBeer);
}
});
}
}
function saveNewBeer(currentBeer) {
var newBeer = new Beer();
newBeer.beerId = currentBeer.beerId;
newBeer.name = currentBeer.name;
newBeer.description = currentBeer.description;
newBeer.abv = currentBeer.abv;
newBeer.image = currentBeer.image;
newBeer.save(function(err) {
if (err) {
throw err;
}
});
}
This code is adding n duplicates (where n = beerObjects.length) of just the last item in beerObjects.
Upvotes: 2
Views: 1867
Reputation: 1570
MongoDB ID is auto-generated so you cannot added any values into _id
property unless you defined _id
as String in your mongoose model.
For example.
var mongoose = require('mongoose');
var beerSchema = new mongoose.Schema({
_id: String,
name: String,
// rest of beer properties
});
module.exports = mongoose.model('Beer', beerSchema);
Inside your function,
function addBeersToDatabase(beerObjects) {
for (i = 0; i < beerObjects.length; i++) {
Beer.findbyId(beerObjects[i].id, function(err, beers){
if (beers.lenght == 0) {
// add new beer to database
var newBeer = new Beer();
newBeer._id = beerObjects[i].id;
newBeer.name = beerObjects[i].name;
newBeer.description = beerObjects[i].description;
newBeer.abv = beerObjects[i].abv;
newBeer.image = beerObjects[i].image;
newBeer.save();
}
else {
// beer is already in database
}
});
}
If you want to use default mongoId, you just need to remove _id: String
in model and newBeer._id = beerObjects[i]id
from your function. I hope this would help you.
Upvotes: 1
Reputation: 13888
Edit:
You are looping through and 'grabbing' a beer with beerObject[i].id
, then you asynchronously check the count, by the time you get down to setting newBeer.id you are in a different scope. The remedy to this is to set a variable to beerObject[i].id
and pass that in as the 'beer' you look for in the Beer.count
:
like so:
for (i = 0; i < beerObjects.length; i++) {
console.log(beerObjects[i].id);
var checkBeer = beerObjects[i]
// check if beer is already in database
Beer.count({id: checkBeer.id}, function(err, count){
if (err) {
handleError(err);
}
if (count == 0) {
// add new beer to database
var newBeer = new Beer();
newBeer.id = checkBeer.id;
... and so on
Upvotes: 1
Reputation: 11
You need to use _id instead of id :
newBeer._id = data[i]['id'];
newBeer.name = data[i]['name'];
Upvotes: 1