2

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.

spatel95
  • 447
  • 1
  • 5
  • 10
  • `i` variable is defined out of scope, you should do it the local or store `id` in the function local var: `var id = beerObjects[i].id;` – alexmac Apr 07 '16 at 21:57

3 Answers3

1

You need to use _id instead of id :

newBeer._id = data[i]['id'];
newBeer.name = data[i]['name'];
JAL
  • 41,701
  • 23
  • 172
  • 300
Amine
  • 11
  • 1
  • Still doesn't work. I created a field called 'id' which is the id of the beer. '_id' is different, that's the mongodb id. So it's not a problem with newBeer, it's a problem with beerObjects. – spatel95 Apr 07 '16 at 21:59
1

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
omarjmh
  • 13,632
  • 6
  • 34
  • 42
  • Same as the other answer. Still doesn't work. I created a field called 'id' which is the id of the beer. '_id' is different, that's the mongodb id. So it's not a problem with newBeer, it's a problem with beerObjects. – spatel95 Apr 07 '16 at 22:03
  • Yes this solved my original problem but now I have another issue. Only the last beer in the list is getting added to my database. Let's say the list length is 10. It is adding 10 copies of the same beer to the database. – spatel95 Apr 07 '16 at 22:32
  • I'm using findOne now and it's still not working. I even tried match the name instead of id but it's still adding duplicates. And the for loop is still looping several times with just the last beer. – spatel95 Apr 07 '16 at 23:07
  • Yes i put it in a new function. Take a look at the edited question. – spatel95 Apr 07 '16 at 23:13
  • http://stackoverflow.com/questions/36506718/mongoose-add-multiple-items-to-database – spatel95 Apr 08 '16 at 18:28
1

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.

Khay
  • 1,530
  • 13
  • 28