How to structure urls in angularjs - angularjs

Currently my url structure in angularjs is as follows. When I load the page I use
Orders.query
and when I try to update using
order.update()
But once I put conditions like search and then fetch orders, update them using
order.update()
it tries to call PUT on conditioned/orders as the new orders are fetched using the Fetch factory method. Is there any better way to merge the urls to make it more meaningful. Is there any standard followed in this sort of cases?
angular.module('orders').factory('Orders', ['$resource',
function($resource) {
return $resource('orders/:orderId', {
orderId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}
]).factory('Search', ['$resource',
function($resource) {
return $resource('search/orders/', {},{
conditioned: {
method:'GET', params:{}, isArray:true
}
});
}
])
Routes on server side(Expressjs) are
app.route('/orders')
.get(orders.list)
.post(users.requiresLogin, orders.create);
app.route('/orders/:orderId')
.get(orders.read)
.put(users.requiresLogin, orders.update)
.delete(users.requiresLogin, orders.delete);
app.route('/search/orders')
.get(orders.search);

Related

How to use Angular Query resource

I'm using MEAN.JS 0.4 and I need some help with Angular Resource.
My problem is this:
I want to make this API and be able to filter data server side, but I dont know how to use this Query method.
I want to do something like this:
Products.query({
stock: 0
}, function(result){
console.log(result)
});
This is my actual Angular service:
//Discounts service used for communicating with the discounts REST endpoints
angular.module('discounts').factory('Discounts', ['$resource',
function ($resource) {
return $resource('api/discounts/:discountId', {
discountId: '#_id'
}, {
update: {
method: 'PUT'
}
});
}
]);
Discounts.query({stock: 0}).$promise
.then(function(data) {
products = data; })
or
products = Discount.query({stock: 0}, function() {
//do something whith products
});

Angular $resource action return $resource of different class

So I have a services.js that looks something like this.
.factory('User', function($resource) {
return $resource('/api/users/:id/', {'id': '#id'}, {
groups: {
method: 'GET',
url: '/api/users/:id/groups',
isArray: true
}
});
})
.factory('Group', function($resource) {
return $resource('/api/groups/:id/', {'id': '#id'}, {
update: {
method: 'PUT'
}
});
})
Users in the db have an implicit relationship to Groups via a JSONField of ids (implicit in that it is not an explicit one2m or m2m). I have a custom endpoint on my api server '/api/users/:id/groups' that returns a serialized array of Group instances. My issue is that the User::groups action on the angular side is returning an array of the Group instances BUT with the actions of the USER resource instead of the GROUP resource. Is there any way for the custom action of a $resource to return an instance of a $resource from a different class?
Thanks!

AngularJS Response does not match configured parameter

I've got a problem with service configuration. I want to display one user by this function:
$scope.findOne = function() {
$scope.user = Users.get({
userId: $stateParams.userId
});
};
But I am in trouble with User service :( I don't know, how should I change my the code to avoid angular error:
Error in resource configuration for action object. Expected response
to contain an array but got an {2}
Here is a code of my actual working service (without function findOne working of course:))
'use strict';
angular.module('users').factory('Users', ['$resource',
function($resource) {
return $resource('users', {}, {
update: {
method: 'PUT'
},
remove: {
method: 'DELETE',
url: 'users/:id',
params: {id: '#_id'}
}
});
}
]);
At a guess, I'd say your users API endpoint is expecting /users/:userId for GET requests. Your code at the moment will request /users?userId=nnn. You need to add an action for get with the ID in the URL, eg
return $resource('users', {id: '#userId'}, {
get: {
method: 'GET',
url: 'users/:id',
isArray: false
},
// etc
You can also make users/:id the default URL as long as it doesn't interfere with your other action configurations.

AngularJS Custom Resource URL being overwritten

I have a custom resource defined as such:
app.factory('SpaceGroupService', ['$resource', function ($resource) {
return $resource('api/SpaceGroup/:id', { id: '#id'},
{
'parkingSpaces': { method: 'GET', url: 'api/SpaceGroup/:id/ParkingSpaces', isArray: true }
});
}]);
The idea is to pass in an ID of my space group object to return all parking spaces in that group. When I call
SpaceGroupService.query()
While running on my local iisexpress it's hitting the correct service url:
/api/SpaceGroup
But when I do:
spaceGroup.$parkingSpaces({ id: spaceGroup.SpaceGroupId }, function (parkingSpaces) {
spaceGroup.parkingSpaces = parkingSpaces;
});
It is querying my restful service as:
/api/SpaceGroup/2
instead of:
/api/SpaceGroup/2/ParkingSpaces
I'm somewhat new to angularJS and I know my route works on my API controller so I'm just trying to get this service to work properly. Any ideas why this overwritten URL isn't called?
I'd would write your service like this instead:
app.factory('SpaceGroupService', ['$resource', function ($resource) {
return
{
ParkingSpaces: $resource('api/SpaceGroup/:id/ParkingSpaces', {},
{
query: { method: 'GET', params: { id: '#id'}, isArray: true }
}
}
}]);
And then call it like this instead:
SpaceGroupService.ParkingSpaces.query({ id: someId });
You can set up multiple resources in the service this way - and you can define multiple methods too (GET, POST, PUT, DELETE). It also means that Angular will honor your $resource url.

Getting a single result with angularjs factory in MEAN stack

I'm trying to grab a single result from my expressjs api from within my AngularJS factory.
The factory looks like this and grabs all posts from my api(written in expressjs and getting data from mongodb), which is working fine:
angular.module('bonsaiService', ['ngResource']).
factory('bonsaiService', function($q,$resource) {
var bonsaiResource = $resource('http://localhost:8888/api/bonsais/:bonsaiId',{},{
get:{
method: 'GET',
params:{bonsaiId:''},
isArray: true
}
});
return {
get:function(){
var q = $q.defer();
bonsaiResource.get({
},
function(resp){
q.resolve(resp);
},function(httpResponse){
q.reject(httpResponse);
});
return q.promise;
}
//find by id
};
});
What i've tried so far is adding :bonsaiId after the $resource url and adding params for that id like this: params:{bonsaiId: ''}.
The server part (expressJS) look like this:
router.route('/bonsais/:bonsaiId')
.get(function(req,res){
Bonsai.findOne(req.params.bonsaiId,function(err,bonsai){
if(err)
res.send(err);
res.json(bonsai)
})
})
When I call a local url (with and existing _id from mongodb) it works fine and returns my data in json :
http://localhost:8888/api/bonsais/536be2e2ae54668818000001
Now in the controller im trying to get this data in my scope, which is not working.
bonsaiService.get({bonsaiId:$routeParams.bonsaiId}).then(
function(data){
$scope.trees = data;
console.log(data);
});
How do I make this work?
You could use a more simple approach here.
The query method for $resource already defines a GET on an array, which is QUERY.
Why not write your service this way :
.factory('bonsaiService', ['$resource',
function($resource) {
return $resource('http://localhost:8888/api/bonsais/:bonsaiId', {
bonsaiId: '#bonsaiId'
});
}
])
And in your controller, it would work like this :
bonsaiService.query({
bonsaiId: $routeParams.bonsaiId
}, function success() {
//Your code
}, function err() {
//Your code
});
Don't forget to inject the service in the controller or the app file, if it's not done already.

Resources