javascript - Number TypeError with Mongoose Model? -
there's 500 internal server error, error: typeerror: path must string
the browser console points itemctrl.js:35
console.log('error: ' + data); the stack trace error looks this:
typeerror: path must string @ query.where (/users/name/downloads/dev/v16/node_modules/mongoose/lib/query.js:593:11) @ function.where (/users/name/downloads/dev/v16/node_modules/mongoose/lib/model.js:1040:18) @ model. (/users/name/downloads/dev/v16/app/models/item.js:44:35) ...
it seems error derives line in /app/models/item.js in else if statement.. because else if commented out, both if works , else works..
// load mongoose since need define schema , model var mongoose = require('mongoose'); var itemschema = mongoose.schema({ title : string, position: number }); // before validation starts, number of items counted..afterwards, position set itemschema.pre("validate", function(next) { var doc = this; // if 'position' not filled in, fill in // not using !position because 0 might valid value if(typeof doc.position !== "number") { // count number of items * // use mongoose.model fetch model because not compiled yet mongoose.model("item").count(function(err, num) { // if there error, pass next() if(err) return next(err); // set position, call next(); doc.position = num; return next(); }); } else if(typeof doc.position == "number") { console.log('yes, number'); // check if there existing document same position // use mongoose.model fetch model because model not compiled yet mongoose.model("item").where({_id: {$ne: doc._id}, position: doc.position}).count( function (err, count) { // if there error, pass next() if(err) return next(err); // if there doc same position, execute update move down $gte docs if(count > 0) { // use mongoose.model fetch model because model not compiled yet mongoose.model("item").update({position: {$gte: doc.position}}, {position: {$inc: 1}}, {multi: 1}, function(err, numaffected) { console.log(numaffected); // call next() (with or without error) next(err); }); } else { // there no docs need move down, call next() next(); } }); } else { // there no need count or update positions, call next() next(); } }); module.exports = mongoose.model('item', itemschema);
- the path of data this:
- form field in /public/views/createitem.html
- to /public/js/controllers/itemctrl.js
- to /public/js/services/itemservice.js
- to /app/routes.js
- to /app/models/item.js
- and data can viewed in json @ localhost:8080/api/items
/public/views/createitem.html
<form> <div class="form-group"> <!-- bind these values formdata.value in angular --> <input type="text" class="form-control input-lg text-center" placeholder="item" ng-model="formdata.title"> <input type="number" class="form-control input-lg text-center" placeholder="0" ng-model="formdata.position"> </div> <!-- createitem() create new item via angular through node api mongoose --> <button type="submit" class="btn btn-primary btn-lg" ng-click="createitem()">add item</button> </form> /public/js/controllers/itemctrl.js
angular.module('itemctrl', []) // inject item service.factory our controller .controller('itemcontroller', function($scope, $http, items, isemptyobjectfilter) { $scope.formdata = {}; // create ================================================================== // when submitting add form, send text node api $scope.createitem = function() { // validate formdata (using our exentions.js .filter) make sure there..if form empty, nothing happen if (!isemptyobjectfilter($scope.formdata)) { // call create function our service (returns promise object) items.create($scope.formdata) // if successful creation, call our function new items .success(function(data) { $scope.formdata = {}; // clear form our user ready enter $scope.items = data; // assign our new list of items }) .error(function(data) { console.log('error: ' + data); }); } }; }); /public/js/services/itemservice.js
angular.module('itemservice', []) // super simple service // each function returns promise object .factory('items', function($http) { return { : function() { return $http.get('/api/items'); }, create : function(itemdata) { return $http.post('/api/items', itemdata); } } }); /app/routes.js
// load item model var item = require('./models/item'); // expose routes our app module.exports module.exports = function(app) { // create item , send items after creation app.post('/api/items', function(req, res) { console.log(req.body.position); // create item, information comes ajax request angular item.create({ title : req.body.title, position : req.body.position }, function(err, item) { if (err) res.send(err); // , return items after create item.find(function(err, items) { if (err) res.send(err) res.json(items); }); }); }); };
the issue here mongoose api doesn't use where way attempting to.
the docs v3.8.8 of mongoose model.where show can use in activerecord style way, chaining property names (like 'age') criteria methods (like gte) form query:
user.find({age: {$gte: 21}, callback) is equivalent to
user.where('age').gte(21).exec(callback) your code uses hash-of-conditions style of model#find instead of chained methods style of where.
this line should rewritten:
mongoose.model("item").where({_id: {$ne: doc._id}, position: doc.position}).count( function (err, count) {
the easiest thing remove .count @ end , change .where .count, since mongoose's model#count takes hash of conditions have here. code should work this:
mongoose.model("item").count({_id: {$ne: doc._id}, position: doc.position}, function (err, count) {
if want use .where syntax you'd need this:
mongoose.model("item").where('_id').ne(doc._id).where('position').equals(doc.position).count( function(err, count)
Comments
Post a Comment