I have a factory that returns the $resource for my Article model:
angular.module('ADI.Resources').factory("Articles", ['$resource', function($resource) {
return $resource('/api/v1/article/:articleId', {
articleId: '#_id',
_shop: window.user._shop
}, {
update: {
method: 'PUT'
}
});
}]);
GET, POST and DELETE are working well, but not the update (PUT). Here is the code I use:
Articles.update({articleId: '300000000000000000000001'}, function(article){
console.log(article);
});
It's making this request:
PUT http://localhost:3000/api/v1/article?_shop=100000000000000000000001
instead of:
PUT http://localhost:3000/api/v1/article/300000000000000000000001?_shop=100000000000000000000001
Any idea why the :articleId parameter is not filled when doing an update? Thanks!
As Fals mentionned in the comment, the articleId parameter was in the request content. So I made a little trick to have it also on the URI.
angular.module('ADI.Resources').factory("Articles", ['$resource', function($resource) {
return $resource('/api/v1/article/:articleId', {
articleId: '#_id',
_shop: window.user._shop
}, {
update: {
method: 'PUT',
params: {
articleId: "#articleId"
}
}
});
}]);
I had the same problem, the issue here was for the following line:
articleId: '#_id',
that line should be:
articleId: '#articleId',
articleId not need to be defined again.
Related
So I'm currently working with $ngResouce. My api: api/Content/resource/user.post.failed returns the following:
{
"user.post.failed": "Thing.."
}
app.factory('testResource', function ($resource) {
return $resource(apiurl + '/Content/resource/:resourcename', {}, {
show: { method: 'GET', isArray: false, params: {resourcename: '#resourcename'} },
update: { method: 'PUT', params: {id: '#id'} },
delete: { method: 'DELETE', params: {id: '#id'} }
})
});
This is what I call in my controller
$scope.test = testResource.get({resourcename: 'test'});
The question is actually really simple; how do I get just the 'content part' so test. I'm now getting the whole JSON part back.
So the scope test is now: {"user.post.failed":"Thing.."}
And I want the scope to be just Thing.
Probably really simple, but I couldn't find the answer.
Use the $promise property of the object to see errors:
$scope.test = testResource.get({resourcename: 'test'});
$scope.test.$promise.catch(function onReject(response) {
console.log('ERROR: ',response.status);
console.log(response);
});
So the scope test is now: {"user.post.failed":"Thing.."} And I want the scope to be just Thing.
console.log($scope.test["use.post.failed"]);
Use the property accessor syntax.
For more info see MDN JavaScript Reference -- Property Accessors
HTML
{{ test["use.post.failed"] }}
testResource.get({resourcename: 'test'}, function(data) {
$scope.test = data['user.post.failed'];
})
Getting the list is not a problem but if I tried to Update or Add a record, it does not seem to work.
Here's the code:
angular.module('userApp.services',[])
.factory('User', function($resource){
return $resource('http://localhost/api/v1/users/:id',
{id:'#id'},
{
update: {
method: 'PUT'
}
});
});
My RESTful service is built in Laravel.
You are not injecting the ngResource module you need to use.
angular.module('userApp.services',['ngResource'])
.factory('User', ['$resource', function($resource){
return $resource('http://localhost/api/v1/users/:id', { id:'#id' }, {
update: { method: 'PUT' }
});
}]);
sample code as follow,Is it about hl?locale? Many thanks.
.factory('newsResource', ['$resource', function($resource) {
return $resource('http://ajax.googleapis.com/ajax/services/search/news?v=1.0&q=%E6%96%B0%E8%81%9E');
}])
newsResource.get(
function(successResponse){
console.log(successResponse);
}
);
You have to use JSONP when making a request to an external domain and it seems the googleapis also support the JSONP.
You could change your $resource to use JSONP instead like this:
.factory('newsResource', function($resource) {
return $resource('http://ajax.googleapis.com/ajax/services/search/news?v=1.0&q=%E6%96%B0%E8%81%9E', {}, {
get: {
method: 'JSONP',
params: { callback: 'JSON_CALLBACK' }
}
});
});
Example Plunker: http://plnkr.co/edit/jCDqCErP9UKLWuhBOtp4?p=preview
I'm following the Angular main page and I've extended $resource to add the update method like this:
angular.module('user', ['ngResource']).
factory('User', function($resource) {
var User= $resource('/user/:id', {
update: {
method: 'PUT'
}
});
User.prototype.update = function(cb) {
return User.update({ // this line throws the error
id: this.id
}, angular.extend({}, this, {
_id: undefined
}), cb);
};
However running:
$scope.user.update()
throws a TypeError: Object function h(a){v(a||{},this)} has no method 'update'
I can't see what I'm missing right now, any help appreciated
I found the issue in fact I need to pass an empty object for the paramDefaults arg:
var User= $resource('/user/:id', {}, {
update: {
method: 'PUT'
}
}
You are using the minified angularjs version, so you have to use to array notation. Just inject the required services in an array followed by the function:
angular.module('user', ['ngResource']).
factory('User', ['$resource', function($resource) {
var User= $resource('/user/:id', {
update: {
method: 'PUT'
}
});
User.prototype.update = function(cb) {
return User.update({
id: this.id
}, angular.extend({}, this, {
_id: undefined
}), cb);
});
}]);
Note: the same applies for your directives, controllers, ...
In resource instances, the method name is prefixed with $.
$scope.user.$update({}, cb);
$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!