4

I m learning nodejs and mongodb altogether with getting MEAN application

my system specifications are

ubuntu 16.04 (64 bit)
node v 6.1.0
npm v 3.8.6

"mongodb": "^2.1.18",
"mongoose": "^4.4.16",

So far I have created schema and add an entry in mongodb collection through terminal using db.locations.save() and get the generated document _id with db.locations.find().

db.locations.find().pretty() in terminal returns below output

{
    "_id" : ObjectId("57428745e89f5c55e1d057dc"),
     // and many other path 
}

Now when I open /api/locations/57428745e89f5c55e1d057dc in browser, it neither gives result nor end the request. permanently show loading.. when testing with postman.

even tried with wrong Id than it returns proper error

{"message":"Cast to ObjectId failed for value \"57428745e89f5c55e1d057dca\" at path \"_id\"","name":"CastError","kind":"ObjectId","value":"57428745e89f5c55e1d057dca","path":"_id"}

and with correct id

console.log(mongoose.Types.ObjectId.isValid(req.params.locationid));  // return true

even tried

findOne({"_id": mongoose.Types.ObjectId(req.params.locationid) })

But no results

What could be the issue? Is there any bug in mongoose or anything missing .Below are my basic files with required code

loc8r/app.js

require('./app_api/models/db');
var routesApi = require('./app_api/routes/index');
app.use('/api', routesApi);

loc8r/app_api/models/db.js

var mongoose  = require( 'mongoose' );    
var mongoURI = 'mongodb://localhost/loc8r';    
var mongoDB = mongoose.createConnection(mongoURI);

mongoDB.on('connected', function (){
    console.log('mongoose connected to ' + mongoURI);
});

require('./locations');

loc8r/app_api/models/locations.js

var mongoose  = require( 'mongoose' );    
var openingTimeSchema = new mongoose.Schema({
days: {type: String, required: true},
opening: String,
closing: String,
closed: {type: Boolean, required: true}
});

var reviewSchema = new mongoose.Schema({
author: String,
rating: {type: Number, required: true, min: 0, max: 5},
reviewText: String,
createdOn: {type: Date, "default": Date.now}
});

var locationSchema = new mongoose.Schema({
    name: {type: String, required: true},
    address: String,
    rating: {type: Number, "default": 0, min: 0, max: 5},
    facilities: [String],
    coords: {type: [Number], index: '2dspehere'},
    openingTime: [openingTimeSchema],
    reviews: [reviewSchema]
});

mongoose.model('Location', locationSchema);

loc8r/app_api/router/index.js

var express = require('express');
var router = express.Router();
var ctrlLocations = require('../controllers/locations');

/* Locations pages */
router.get('/locations/:locationid', ctrlLocations.locationsReadOne);

loc8r/app_api/controllers/locations.js

var mongoose = require('mongoose');
var Loc = mongoose.model('Location');

module.exports.locationsReadOne =  function (req, res) {
    if(req.params && req.params.locationid) {            
        Loc
        .findById(req.params.locationid)
        .exec(function(err, location) {
            if(err) {
                sendJsonResponse(res, 404, err);
                return;
            }
            if (!location) {
                sendJsonResponse(res, 404, {"message": "locationid not found"});
                return;
            }
            sendJsonResponse(res, 200, location);
        });
    } else {
         sendJsonResponse(res, 200, {"message": "no location id in request"});
    }
}

var sendJsonResponse = function(res, status, content) {
    res.status(status);
    res.json(content);
};
xkeshav
  • 53,360
  • 44
  • 177
  • 245
  • Possible dupe http://stackoverflow.com/questions/15771470/mongoose-cast-to-objectid-failed-for-value – chridam May 23 '16 at 07:21
  • Sorry but that does not solve my problem. already search over google and mongoose github issues. – xkeshav May 23 '16 at 07:25
  • Did you try the other answer? – chridam May 23 '16 at 07:29
  • yes. I have created new document and tried too. not helped – xkeshav May 23 '16 at 08:31
  • Are you sure that `locationsReadOne` is getting reached at all? Are you using some kind of middleware in your app that may be causing the request to hang? – robertklep May 23 '16 at 09:22
  • how do I find that? as i have set `console.log()` inside **locationsReadOne** and it appears on console. is there anything else? I also suspect that something is blocking the request – xkeshav May 23 '16 at 09:33
  • If the `console.log()` appears you should be okay there. You can try the same for `sendJsonResponse()` but it looks to me like that should always be called as well. – robertklep May 23 '16 at 09:35
  • Are you able to reach `module.exports.locationsReadOne` when you debug application? – maulik sakhare Jun 01 '16 at 05:58

5 Answers5

4

I was having a similar issue, so I updated my Model file. For e.g.

const workoutsSchema = new Schema({
  _id: mongoose.ObjectId,
  email_add: String,
  workout_date: String,
  workout_duration: String
});

In the controller:-

  router.route("/workouts/:id").get(function(req, res) {
  console.log("Fetch Workouts of="+req.params.id);
  var id = new mongoose.Types.ObjectId(req.params.id);
  Workouts.findById(id, function(err, workout) {
        if (err)
            res.send(err)
        res.json(workout);
    });
});
SumanD
  • 41
  • 1
2

1. console your req.params before if

loc8r/app_api/controllers/locations.js

var mongoose = require('mongoose');
var Loc = mongoose.model('Location');

module.exports.locationsReadOne =  function (req, res) {

console.log(req.params)

    if(req.params && req.params.locationid) {            
        Loc
        .findById(req.params.locationid)
        .exec(function(err, location) {
            if(err) {
                sendJsonResponse(res, 404, err);
                return;
            }
            if (!location) {
                sendJsonResponse(res, 404, {"message": "locationid not found"});
                return;
            }
            sendJsonResponse(res, 200, location);
        });
    } else {
         sendJsonResponse(res, 200, {"message": "no location id in request"});
    }
}

var sendJsonResponse = function(res, status, content) {
    res.status(status);
    res.json(content);
};

if params empty, or console not work, then check your route path

or

  1. console something inside sendJsonResponse, maybe your function not work. Because if permanently show loading, it mean you dont send response.

or

  1. Try to update mongodb to latest version, maybe mongoose work not correct with mongodb 2.1.18. It`s realy very old version.
cheks
  • 340
  • 1
  • 2
  • 16
  • `console.log(req.params)` outputs *{ locationid: '57428745e89f5c55e1d057dc' }* – xkeshav Jun 06 '16 at 04:28
  • also upgraded mongodb to 3.2.6 but still no difference – xkeshav Jun 06 '16 at 04:42
  • ever if I change last character of `locationid` , it doesn't throw any error – xkeshav Jun 06 '16 at 04:51
  • Try enother query to enother collection. Maybe problem with moongoose conection... Or try find with enother filed. – cheks Jun 06 '16 at 08:19
  • sorry but latest mongodb can't be installed on my ubuntu 16.04 / also tried with other collections as well but same issue. see my next problem [Here](http://stackoverflow.com/questions/37656700/mongoose-does-not-create-document) – xkeshav Jun 06 '16 at 12:56
2

get the solution from mongoose documentation

Important! If you opened a separate connection using mongoose.createConnection() but attempt to access the model through mongoose.model('ModelName') it will not work as expected since it is not hooked up to an active db connection. In this case access your model through the connection you created:

so changing the way I create the connection

//var mongoDB = mongoose.createConnection(mongoURI);
mongoose.connect(mongoURI);

also need to comment all other functions/expression which use mongoDB variable


Alternative approach : ( if you do not want to change mongoDB in db.js )

in controllers/locations.js

change var Loc = mongoose.model('Location'); with below line

var conn = mongoose.createConnection('mongodb://localhost/loc8r');
var Loc = mongoose.model('Location');
xkeshav
  • 53,360
  • 44
  • 177
  • 245
0

try rewrite location controller like this

var mongoose = require('mongoose'),
    Location = mongoose.model('Location');

exports.locationsReadOne = function (req, res) {
    if (req.params && req.params.locationid)
        Location.findById(req.params.locationid, function (err, location) {
            if (err) return res.status(500).send(err);
            if (location) return res.status(200).json(location);
            return res.status(404).json({"message": "locationid not found"})
        })
    else
        return res.status(200).json({"message": "no location id in request"})
}
KibGzr
  • 2,053
  • 14
  • 15
0

Hey try by converting your id to object id

var mongoose = require('mongoose'),
Location = mongoose.model('Location');

exports.locationsReadOne = function (req, res) {
if (req.params && req.params.locationid)
    Location.findById(mongoose.Types.ObjectId(req.params.locationid), function (err, location) {
        if (err) return res.status(500).send(err);
        if (location) return res.status(200).json(location);
        return res.status(404).json({"message": "locationid not found"})
    })
else
    return res.status(200).json({"message": "no location id in request"})
}
Mariya James
  • 935
  • 2
  • 9
  • 27