user1086010
user1086010

Reputation: 697

Node.js Object [object Object] has no method error

I am using Express.js for my app and mongodb for database (also mongodb Nativ driver).

I created a model with two functions, for getting posts and comments:

// Get single Post
exports.posts = function(id,callback){

    MongoClient.connect(url, function (err, db) {
      if (err) {
        console.log('Unable to connect to the mongoDB server. Error:', err);
      } else {

        console.log('Connection established to', url);

        var collection = db.collection('posts');

        collection.find({psotId:id}).limit(1).toArray(function (err, result) {
          if (err) {
            return callback(new Error("An error has occured"));
          } else {
            callback(null,result);
          }
          db.close();
        });
      }
    });

}

// Get post comments
exports.comments = function(id,callback){

    MongoClient.connect(url, function (err, db) {
      if (err) {
        console.log('Unable to connect to the mongoDB server. Error:', err);
      } else {      
        console.log('Connection established to', url);
        var collection = db.collection('comments');
        collection.find({postId:id}).toArray(function (err, result) {
          if (err) {
            return callback(new Error("An error has occured"));
          } 
          else {        
            callback(null,result);
          }
          db.close();
        });
      }
    });

}

and I created a route to show single post:

var post = require('../models/post');
 //Get single post
router.get('/post/:postId',function(req,res, next){

    var id = parseInt(req.params.postId);
    post.posts(id,function(err,post){
        if(err){
            console.log(err)
        }else{
            post.comments(post[0].id,function(err,comments){
                if(err){
                    console.log(err)
                }
                else{
                    res.render('blogPost',{post:post,comments:comments})
                }
            })
        }
    })

})

When I run this code I get this error:

TypeError: Object [object Object] has no method 'comments'

When I use this two function separately its work fine:

I mean like this :

var post = require('../models/post');
 //Get single post
router.get('/post/:postId',function(req,res, next){

    var id = parseInt(req.params.postId);
    post.posts(id,function(err,post){
        if(err){
            console.log(err)
        }else{
           res.render('blogPost',{post:post})   
        }
    })

})





     //Get post comments
router.get('/post/1',function(req,res, next){

    post.comments(1,function(err,comments){
        if(err){
            console.log(err)
        }else{
           res.render('blogPost',{comments:comments})   
        }
    })

})

But when I use post.comments as callback for post.posts I get an error.

I wants know why this happening? After some research I couldn't find a solution and I an getting confused.

Upvotes: 0

Views: 81

Answers (2)

DevAlien
DevAlien

Reputation: 2476

In your source code you have the following:

var post = require('../models/post');
 //Get single post
router.get('/post/:postId',function(req,res, next){

    var id = parseInt(req.params.postId);
    post.posts(id,function(err,post){
        if(err){
            console.log(err)
        }else{
            post.comments(post[0].id,function(err,comments){
                if(err){
                    console.log(err)
                }
                else{
                    res.render('blogPost',{post:post,comments:comments})
                }
            })
        }
    })

})

when you are calling post.posts you have a callback and there you have a return value which you called post (which it is the same variable name of var post = require('../models/post');

Basically change it in the callback like this:

var post = require('../models/post');
 //Get single post
router.get('/post/:postId',function(req,res, next){

    var id = parseInt(req.params.postId);
    post.posts(id,function(err,posts){ //HERE changed post into posts
        if(err){
            console.log(err)
        }else{
            post.comments(posts[0].id,function(err,comments){
                if(err){
                    console.log(err)
                }
                else{
                    res.render('blogPost',{post:posts,comments:comments})
                }
            })
        }
    })

})

EDIT: for better understanding I would change var post = require('../models/post'); into var postModel = require('../models/post'); SO it is much more understandable

EDIT 2: since he posted the real version code

Basically you have the same problem, line 37 of route.js is overriding the movie variable. You have to call the variable that comes back form the callback with another name, for example movieslike you used to do in the other 2 above.

router.get('/m/:movieId',function(req,res, next){

    var id = parseInt(req.params.movieId);
    movie.get(id,function(err,movies){
        if(err){
            console.log(err)
        }else{
            movie.subtitles(movies[0].imdb,function(err,subs){
                if(err){
                    console.log(err)
                }
                else{
                    res.render('moviePage',{movie:movies,subtitles:subs})
                }
            })
        }
    })

})

Upvotes: 2

micah
micah

Reputation: 8106

If you copy-pasted this from your source then its because you mispelled the method.

post.commencts

should be

post.comments

Upvotes: 0

Related Questions