I'm learning the MEAN stack. I have a node api hooked up to MongoLab hosted DB.
The api returns objects like this (api/messages
):
[
{
_id: "55074ce3c21903c9cce6d02a",
name: "some random message",
__v: 0
},
{
_id: "55074e4a1dad546fcef09769",
name: "a different message",
__v: 0
},
{
_id: "55074e4a1dad546fcef09123",
name: "bingo",
__v: 0
}
]
With restangular, I get the data and then bind to $scope
:
Restangular.all('api/messages').getList().then(function (data){
$scope.messages = data;
});
In one part of the app, I want to query/return only necessary data - something like this:
Restangular.all('api/messages').customGET('', {"q": {"name": "a different message" }}).then(function (data) {
console.log(data);
});
I want to only return objects that contain X - in this case, 'a different message'.
However, the customGET
method doesn't seem to work as I expect; I always get all of the objects.
How can I achieve this? I've been searching and trying things out for a while with no success. Maybe I need to add some api routes and methods.
Any help would be v.appreciated :)
The answer is to send the API an object for the query you want. After reading the query correctly, the API can then query the DB and return the data.
Here is a step-by-step example:
angular controller
In my case, I want to create a query with multiple items from an automatically generated array. For simplicity:
var randomUsernames = [
'bill', 'ben', 'james', 'phil'
];
Then we create an object for Restangular:
var objectForRestangular = {
randomUsernames : randomUsernames
}
Now we can do a Restangular customGET
promise:
Restangular.all('api').customGET('messages', objectForRestangular).then(function (data){
$scope.items = data;
}, function (err){
console.warn('oh no!', err);
});
This will generate an api endpoint like this:
/api/messages?randomUsernames=bill&randomUsernames=ben&randomUsernames=james
node API
We can use express's req.query
to reference the string parameters in the route:
router.route('/messages')
.get(function (req, res) {
var usernames = req.query.randomUsernames;
console.log('we have ' + usernames.length + ' usernames: ' + usernames)
});
querying the db
An example object:
{
_id: '123123123123123'
username: 'thor',
time: '09/08/2015',
copy: 'hey guys, have you seen this? http://random.org',
userLikes: [
{
username: 'bill', //check this for a match
_id: '34567890'
},
{
username: 'ben', //check this for a match
_id: '67890132'
}
]
},
{ ... },
{ ... }
I want to return any objects from the DB that contain a matching value from our query randomUsernames
, in the nested array userLikes
.
I'm using Mongoose for DB operations, so we can use the $in
operator. It's perfect for such a query. All together:
router.route('/messages')
.get(function (req, res) {
var usernames = req.query.randomUsernames;
console.log('we have ' + usernames.length + ' usernames: ' + usernames)
Message.find( { username: { $in: userLikes } }, function (err, messages) {
if (err) {
res.send(err);
} else {
res.json(messages);
}
});
});
So now you can use Restangular's customGET
method to send a query to the API, which queries the DB and then returns the data. :-)
If anyone is interested there is an example of this and much more here.
Please note that the examples in this answer are just mock data (eg, 'messages', 'Message' etc).