Angular $resource not working correctly - angularjs

I am trying to build my first Angular $resource to give my application access to CRUD operations, but for some reason the actions being configured for the resource are not defined when I try to execute a query.
Here is my controller logic:
app.controller('MainCtrl', function ($scope, $http, $resource) {
var Alert = $resource('/WebApi/Alert/:type/:id',
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
$scope.systemUpdate = function (alert) {
var data = Alert.systemUpdate({ type: alert.Status, id: alert.AlertId }); // THIS LINE FAILS
console.log(data);
}
I get an error saying that Alert.systemUpdate is not defined. Am I doing something wrong here when configuring my $resource?

Change the definition of your Alert to
var Alert = $resource('/WebApi/Alert/:type/:id',
{},
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
As mentionned in the documentation of $resource, the order of the parameters is the following:
1) Url
2) The default value of the parameters of the url, since you don't have any default value, you must provide an empty object
3) The actions (systemUpdate & autoArchive here)

Related

AngularJs params give all objects with one id

I want to get a single object from json file using AngularJs params, but it give me all objects.
This is the code I've used,
(function () {
"user strict";
angular
.module("myApp")
.controller("indexCtrl", function ($scope, $http, $routeParams) {
var workId = $routeParams.id;
$http({
url: "data/work.json",
method: "GET",
params: {id: workId}
}).then(function(sitedata) {
$scope.workDetail = sitedata.data;
});
});
})();
Please help me. Thanks
If you're loading a json file it will just return the whole content, you'll have to filter in the then callback:
$http({
url: "data/work.json",
method: "GET"
}).then(function(sitedata) {
var match = sitedata.data.filter(function(item) {
return item.id == workId;
});
if (match.length) {
$scope.workDetail = match[0];
}
});

How to update angular resource urls with id from the authenticated user?

So I have defined multiple angular factories with ngResource similar to:
.factory('factoryName', ['$resource', '$http', 'CONSTANTS', 'authService', factoryNameCtrl])
function factoryNameCtrl($resource, $http, CONSTANTS, authService) {
var actions = {
'get': {
method: 'GET',
isArray: false,
params: {
service: '#service',
action: '#action'
}
},
'post': {
method: 'POST',
isArray: false,
params: {
service: '#service',
action: '#action'
}
}
}
actions.get.params.userId = actions.post.params.userId = '#' + authService.currentUser.id;
var res = $resource(CONSTANTS.baseURL + '/:userId/integrations/:service/:action', {}, actions);
If I log in and logout with another user, the value of userId inside the factory doesn't update.
I don't want to pass userId into each params from all over my code, but to make it available when it changes.
Previously I had the code below and I was forcing a page reload to rebuild the correct urls into the resource.
if (authService.isAuthenticated()) {
var res = $resource(CONSTANTS.baseURL + '/' + authService.currentUser.id + '/integrations/:service/:action', {}, actions);
return res;
}
What do you advise to do?
To compute it fresh every time, use a function:
actions.get.params.userId = function () {
return computeCurrentUserId();
};
From the Docs:
If a parameter value is a function, it will be executed every time when a param value needs to be obtained for a request (unless the param was overridden).
-- AngularJS $resource API Reference

POST to nested RESTful resources with $resource parameter mismatch - AngularJS

I'm trying to using the $resource library of angular, to POST data to a nested resource.
My following nested resource of event looks like so
events/:eventId/match - POST
events/:eventId/match - GET
events/:eventId/match/:matchId - GET
I set up a service with angular
app.factory('EventService', ['$resource', function ($resource) {
var Event = $resource('/events/:eventId', {eventId: '#id'},
{
createMatches: {
url: '/events/:eventId/match',
method: 'POST'
}
);
return {
createMatches: function(data,event_id) {
var data.eventId = event_id;
return Event.createMatches(data).$promise;
}
}
});
Controller where it has been called:
app.controller('EventController', ['$scope','EventService', function($scope,EventService) {
$scope.create = function(event_id,title,description) {
EventService.createMatches({
title:title,
description: description
},event_id).then(function(result) {
console.log('event_created', result);
})
}
}]);
Problem
When I send the request to the server I expect the url that looks like so: /events/10/match
But instead the resource doesn't add the eventId as a parameter of the url but add it as a parameter of the request, for this reason my call fail because the url looks like so: /events/match.
I can't understand why it doesn't bind the :eventId to the url. Any suggest will be appreciated.
I believe that you are missing your second parameter decalaration, as per this link for the actions you are defining:
app.factory('EventService', ['$resource', function ($resource) {
var Event = $resource('/events/:eventId', {eventId: '#id'},
{
createMatches: {
url: '/events/:eventId/match',
method: 'POST',
params: {eventId: '#id'}
}
);
return {
createMatches: function(data,event_id) {
var data.eventId = event_id;
return Event.createMatches(data).$promise;
}
}
});

Uncaught Error when using Angular Factory to provide API calls

I am trying to build a service to give my application full access to every single API resource available from a single service. Right now I have created my main Angular app module and an API service called APIService. The service has a factory that returns a number of accessible Angular $resource's to the different APIs. Here is the code.
var app = angular.module('MYAPP', ['ngRoute', 'ngSanitize', 'ngResource', 'apiService']);
var APIService = angular.module("apiService", ["ngResource"]);
APIService.factory("API", function ($resource) {
var apiFactory = {};
apiFactory.Alerts = $resource('/WebApi/Alert/:type/:id', {id:'all'},
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
return apiFactory;
});
However, when I try to load the page, I get an Uncaught Error within the angular.js file. Am I doing something wrong here?
You've forgotten to define a function inside your object:
apiFactory.Alerts = function(){
return $resource('/WebApi/Alert/:type/:id', {id:'all'},
{
systemUpdate: { method: 'GET' },
autoArchive: { method: 'POST', url: '/WebApi/Alert/Template/:type' }
});
}

AngularJS - $resource different URL for Get and Post

$resource is awesome providing very convenient way to handle web services.
What if GET and POST have to be performed on different URLs?
For example, GET URL is http://localhost/pleaseGethere/:id
and POST URL is http://localhost/pleasePosthere without any parameter
Use 'url' property of [actions] to override the default url.
$resource(url, [paramDefaults], [actions], options);
for example:
$resource('http://localhost/pleaseGethere/:id',{},{
getMethod:{
method:'GET',
isArray:true
}
postMethod:{
url:'http://localhost/pleasePosthere',
method:'POST',
isArray:false
}
}
Usage of Angular $resource: http://docs.angularjs.org/api/ngResource/service/$resource
You should be able to expose the URL as a parameter. I was able to do this:
$provide.factory('twitterResource', [
'$resource',
function($resource) {
return $resource(
'https://:url/:action',
{
url: 'search.twitter.com',
action: 'search.json',
q: '#ThingsYouSayToYourBestFriend',
callback: 'JSON_CALLBACK'
},
{
get: {
method: 'JSONP'
}
}
);
}
]);
Then you can overwrite the URL on your GET call.
The one caveat I found during my REALLY brief testing was that if I included http:// in the URL string, it didn't work. I didn't get an error message. It just did nothing.
If you add the hash with param names into the $resource call:
$resource('localhost/pleaseGethere/:id', {id: '#id'});
Then the :id will be mapped to id param when invoking the function (this will call GET localhost/pleaseGethere/123):
Resource.get({id: 123});
For POST, you simply don't assign the id param:
Resource.post({}, {name: "Joe"});
The proper URL will be called, which is in this case POST localhost/pleaseGethere (the trailing slash is stripped by ngResource).
See http://docs.angularjs.org/api/ngResource.$resource -> Examples -> Credit card resource for more details.
In addition to Iris Wong's answer, I wanted to give an example of having multiple params with multiple methods and actions:
angular
.module('thingApp')
.factory('ThingResource', ['$resource', '$state', returnThing]);
And the resource:
function returnThing($resource, $state) {
var mainUrl = '/api/stuffs/:stuffId/thing'
var params = {stuffId: '#_id', thingMongoId: '#_id', thingNumber: '#_id'}
return $resource(mainUrl, params, {
'save': {
url: '/api/stuffs/:stuffId/thing/:thingMongoId',
method: 'POST',
interceptor: {
responseError: function(e) {
console.warn('Problem making request to backend: ', e)
$state.go('oops')
}
}
},
'get': {
url: '/api/stuffs/:stuffId/thing/:thingMongoId',
method: 'GET',
interceptor: {
responseError: function(e) {
console.warn('Problem making request to backend: ', e)
$state.go('oops')
}
}
},
'assignThing':{
method: 'POST',
url: '/api/stuffs/:stuffId/thing/assign/:thingNumber'
}
});
}
Which gives 3 separate methods:
// POST to http://currnt_base_url/api/stuffs/:stuffId/thing/:thingMongoId
ThingResource.save({
stuffId:'56c3d1c47fe68be29e0f7652',
thingMongoId: '56c3d1c47fe6agwbe29e0f11111'})
// GET to current http://currnt_base_url/api/stuffs/:stuffId/thing/:thingMongoId
ThingResource.get({
stuffId:'56c3d1c47fe68be29e0f7652',
thingMongoId: '56c3d1c47fe6agwbe29e0f11111'})
// POST to http://currnt_base_url/api/stuffs/:stuffId/thing/assign/:thingNumber
ThingResource.assignThing({
stuffId:'56c3d1c47fe68be29e0f7652',
thingNumber: '999998'})
Follow this way:
(function () {
'use strict';
angular
.module("app")
.factory("SomeFactory", SomeFactory);
function SomeFactory($resource) {
var provider = "http://stackoverflow.com/:action/:id";
var params = {"id":"#id"};
var actions = {
"create": {"method": "POST", "params": {"action": "CreateAwesomePost"}},
"read": {"method": "POST", "params": {"action": "ReadSomethingInteresting"}},
"update": {"method": "POST", "params": {"action": "UpdateSomePost"}},
"delete": {"method": "GET", "params": {"action": "DeleteJustForFun"}}
};
return $resource(provider, params, actions);
}
})();
I hope it help! Enjoy!

Resources