Trouble with $gt in mongoose - angularjs

I've successfully queried what I'm trying to in the mongo CLI, with the following query.
db.catches.find({'weightTotal': {'$gte' : 150} })
However, when I try to send a query up from angular to the route as such (with a little more specificity):
Hatchery.getByLocation(
{
'x': $scope.y.x._id,
'city': place.data[0].city,
'weightTotal': {'$gte' : 150 }
})
I get the usual error when something blows up in mongoose:
TypeError: Cannot call method 'toString' of undefined
at ServerResponse.writeHead (http.js:1180:45)
at ServerResponse.writeHead (/Users/ShiftedRec/x/y/node_modules/express-session/node_modules/on-headers/index.js:53:19)
But more specifically (console logging the error)
{ message: 'Cast to number failed for value "{"$gte":150}" at path "weightTotal"',
name: 'CastError',
kind: 'number',
value: '{"$gte":150}',
path: 'weightTotal' }
I've gotten this to work by doing a .where in the route, but I'd rather fit everything in the query. It can keep my routes cleaner if I just pass what I need to into a query instead of doing conditional where statements based on permissions etc.
The route the query is passed to looks like this:
router.get('/', function (req, res, next) {
User
.find(req.query)
.populate('post')
.exec(function (err, data){
if (err) return next(err);
res.json(data);
});
});
req.query console logs into this:
{ x: '5581efdcc465c1ccd97a1f6b',
y: '5581efe2458256f5d9848ca7',
weightTotal: '{"$gt": 150}' }
I'm using Mongoose 4.0.1.
Any ideas?

GET requests queries are strings, so if you send this:
www.mysite.com/?data=1&weightTotal=5
You will get this (strings and not numbers):
{data: "1",
weightTotal: "5"}
In order to use the data you can parse it somehow, for example:
req.query.weightTotal = JSON.parse(req.query.weightTotal);
or if it's just a number, a faster parse is:
req.query.weightTotal = +req.query.weightTotal;
A smarter solution, if you are sending objects in your requests, will be to use POST and not GET.

Try converting the req.query.weightTotal string to an object first:
req.query.weightTotal = eval('(' + req.query.weightTotal + ')');
Check the demo below.
var obj = {
x: '5581efdcc465c1ccd97a1f6b',
y: '5581efe2458256f5d9848ca7',
weightTotal: '{"$gt": 150}'
}
obj.weightTotal = eval('(' + obj.weightTotal + ')');
pre.innerHTML = JSON.stringify(obj);
<pre id="pre"></pre>

Related

How to pass an array of object as parameters in Restangular?

I have no idea how i can pass an array of object in Restangular. I've read their documentation. I found that they provided such as customGET, customPOST etc. But, i didn't see the right example that related to my case. For now, i want it to get data from an API that needs params as its filter.
1) Params
var filter = {
category: 1,
page: 1,
product: 20,
price_range: ['bt',1,150]
}
2) Services
getRawList: function(filter) {
return rawProducts.customGET('',filter).then(function(response) {
return response;
});
},
What i got was an Internal Server Error. Any idea how to tackle this error ?
When sending data to a web server, the data has to be a string. So, on this situation i need to convert the array property to string (which is price_range) before send it to the server as filter. This code solved my question.
getRawList: function(filter) {
return rawProducts.customGET('',{
category: filter.category,
page: filter.page,
product: filter.product,
price_range: JSON.stringify(filter.price_range)
}).then(function(response) {
return response;
});
}

Update boolean with Mongoose

I have created an app where i can create a to do list. And i have a status that is false when created. The status i supposed to represent if the object done or not.
My mongoose schema look like this in server.js:
// Create mongoose schema
var issueSchema = mongoose.Schema ({
issue: String,
date: String,
status: Boolean,
});
// Create mongoose model
Issue = mongoose.model('Issue', issueSchema);
When i press my button in on my index.html im using angular to send the id trough to the server.js file.
// API PUT ========================
app.put('/issueList/:id', function(req, res){
var id = req.params.id;
Issue.findById(id, function(err, Issue) {
console.log("Object with ID: " + id); // Correct ID
// I need code here
});
});
I need help updating the boolean value to true if false or false if true. Or should i skip the boolean value and use something else?
You can find the issue by id and then save it back to MongoDB after making the changes in success callback.
Issue.findById(id, function(err, issue) {
issue.status = !issue.status;
issue.save(function (err) {
if(err) {
console.error('ERROR!');
}
});
});
I am not sure about the possibility of toggling boolean field atomically as of now in MongoDB.
First, i dont think you should use same variable name outside and inside the function. In this case Issue is same, change it to issue.
And you can try this to update.
Issue.findById(id, function(err, issue) {
console.log("Object with ID: " + id); // Correct ID
issue.status = !issue.status;
issue.save(function(err,result){...});
});
});

node api not receiving json data

I am using angular to call into a node get api. "undefined" is being received by node for req.query.reqdata Am I supposed to parse the JSON on the server side? Any help will be greatly appreciated.
Client:
function playOrError(instrument, octave, scaletype, basenote) {
var reqdata = {
"instrument" : instrument,
"octave" : octave,
"scaletype" : scaletype,
"basenote": basenote
};
$http.get("/api/getfile", reqdata)
.then(
function(response) {
console.log("File request: " + response.data);
},
function(error) {
console.log("File request failed: " + error);
});
}
Server:
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}));
...
app.get('/api/getfile', function(req, res, next) {
console.log(req.reqdata)
var instument = req.query.instrument
console.log(instrument)
})
reqdata is only the variable name you are using on the client side, and is never seen by express. Rather, console.log(req.query); should log an object (which is the reqdata object you pass into it); This object should have the values you added to that reqdata object, like so:
{
"instrument" : instrument,
"octave" : octave,
"scaletype" : scaletype,
"basenote": basenote
}
Then you can get the instrument for example by doing req.query.instrument
This is similar to when you pass a variable into a function. Just because the variable is named something when you pass it as an argument doesn't mean the function will use the same name! In this case, reqdata is passed in as the req.query
I figured this one out. Bennett was close, but it needs the first value to be params. This way you can send a whole bunch of query parameters via object notation.
$http.get("/api/getfile", {params : reqdata})
I also ended up converting te GET into POST eventually.

Posting Schema.Types.ObjectId arrays to MongoDB

How can I post an array of Schema.Types.ObjectId (s) to MongoDB? I'm trying to create User Groups, which is a group of the 'User' Model e.g.
var UserGroup = new Schema({
users: [{
type: Schema.Types.ObjectId,
ref: 'User'
}]
});
New UserGroup Function
module.exports.create = function(request, response) {
var group = new UserGroup({
users = request.body.users
});
group.save(function(error) {
if(error) { throw error; } else { response.send('Group Created Successfully.');
});
};
I'm currently using Postman to test the functionality, how exactly should the data be posted?
As a Javascript array i.e ['A_USER_ID', 'A_USER_ID'] ?
Thanks!
#Answer
I was using the older syntax of the select() function, and therefore was passing invalid parameters to the $push function. When sending the request, I simply pass the ObjectIds as id,id,id and once they get to the server, simply put it into an array using var my_array = request.body.users.split(','); and then push it to the database using the following:
$push: { users: { $each: my_array } }
I hope this was helpful, the documentation isn't particularly clear on this matter.

How to pass query param to parse-rest-api from angularjs $http service?

I'm learning AngularJS , i set-up a development environment using sublime-text as editor and parse.com-rest-api used as back-end layer.
I came across a scenario where, I have to fetch data based on an attribute.
Below given code from the service layer of angularjs has fetch all records from table 'filim'.
var config = {
headers: {
'X-Parse-Application-Id': 'bNtp8FUfr0s1UsAwJr7MFjabCI31HytIuC3gCaJ2',
'X-Parse-REST-API-Key': 'g18cAoH7QkrBZenPqH0pynMKsn6pj4MyfDyIy6X1',
}
};
return {
getFilims: function(callback) {
var filims;
var resp = $http.get('https://api.parse.com/1/classes/filim', config).success(function(data) {
callback(data.results);
});
}
}
I have modified above url to send query-parameter to filter the output, but did not work.
I refer parse.com api doc [ https://www.parse.com/docs/rest#queries ] to modify url to send query - param.
Modified code is given below,
var params = {"where": {"status" : "CLOSED" } }
var resp = $http.get('https://api.parse.com/1/classes/filim?%s' % params, config).success(function(data) {
callback(data.results);
});
But this did not work.
Is this the way to use query-parameter ?
Regards
Ajil
'https://api.parse.com/1/classes/filim?%s' % params
This is a python pattern for interpolating strings and will not work in javascript.
The correct way of combining strings in javascript is:
'https://api.parse.com/1/classes/filim?' + params
Even still, that will probably not work because you'll end up with something like:
'https://api.parse.com/1/classes/filim?[Object object]
What you need to do for parse.com is to JSON encode the query, so try this:
var whereQuery = {"status" : "CLOSED"};
var url = 'https://api.parse.com/1/classes/filim?where=' + encodeURI(JSON.stringify(whereQuery));
var resp = $http.get(url, config).success(function(data) {
callback(data.results);
});

Resources