rihurla
rihurla

Reputation: 403

Node.js, Express and Mongoose, undefined data

Just a noob problem:

I'm trying to use the property "cover" to delete a file related to that collection, but the problem is that it show as "undefined". Did anyone had a problem like this ?? Thanks !!!

Here is my Log:

FULL RESULT - { __v: 0, _id: 5329a730e4b6306a08297318,

company: 'asd',

cover: '44f4a87035bd22c1995dcf0ab8af05b0',

description: 'asd',

kind: 'asd',

name: 'asd' }

RESULT COVER - undefined

Here is my code:

exports.delete = function(req,res){

if(!req.session.authorized){
    res.json(403,{message:'YOU MUST BE LOGGED IN'});
    return;
}


Product.find({_id:req.params.id}, function(err,result){

    if (err){
        res.json(401, {message: err});

    }else{
        console.log("FULL RESULT - " + result);
        console.log("RESULT COVER - " + result.cover);

        var prodCoverName = result.cover;

        if (prodCoverName){

            fs.exists('public/productAssets/'+ prodCoverName, function (exists) {
                console.log('EXIST - public/productAssets/'+ prodCoverName);
                fs.unlink('public/productAssets/'+ prodCoverName, function (err) {

                    if (err) throw err;
                    console.log('DELETED AT public/productAssets/'+ prodCoverName);

                });

            });

        }

    } 

});

Product.findOneAndRemove({_id:req.params.id}, function(err,result){

    if (err) res.json(401, {message: err});
    else res.json(200, {message: result});

});

};

Upvotes: 1

Views: 630

Answers (1)

Farid Nouri Neshat
Farid Nouri Neshat

Reputation: 30420

I'm not expert in mongoose, but my guess is that Product.find function, will call it's callback with an array of documents, instead of a single document, So you should change your code with the following:

Product.find({_id:req.params.id}, function(err, results){
   var result = results[0]; // either one result or nothing, because id is unique and we want the first result only.

Or use findOne instead(this one callbacks with the first result, faster):

Product.findOne({_id:req.params.id}, function(err, result){

Or use findById(shorter and faster):

Product.findById(req.params.id, function(err, result){

Now you might ask, why in my case, FULL RESULT, is an object. Here's what happens in javascript:

You have console.log("FULL RESULT - " + result), here you are logging a string and you have string concatenation operation, between a string and an array. When you trying to concat a string with a non-string, javascript tries to coerce it into a string, so on cases where it's not undefined/null it will call .toString method of the value. .toString method of an array actually does return this.join(','). join method is also a string concatenation. The array contains documents, so javascript tries to convert the documents into strings(they are objects actually) and it calls the document.toString(). That is implemented by mongoose to return the object properties, which should be something similar to util.inpsect(document);. Another example to this incident is getting result is 1 from 'result is ' + [1].

To avoid this problem, I suggest, just avoid concatenting objects with strings. Instead of console.log('result is ' + object) try to do console.log(object) or console('result is', object).

Update:

I just realized you are also calling findOneAndRemove at the same time you are calling find, this is a race condition. It might happen that .find call wouldn't find anything, because .findOneAndRemove might have been already done. This might introduce more problems.

Upvotes: 2

Related Questions