Angular $resource PUT method, can't make it work - angularjs

I use a REST api and I'd like to update on of my project objects with a PUT request. The request is supported in the API, and I'm trying to use $resource to PUT the data, but it doesn't seem to work. Here is what I do :
var projectResource = $resource('/api/projects/' + projectId, {update: {method: "PUT"}});
$scope.editProject = function(editedProject) {
projectResource.$update(editedProject);
}
Where editedProject is the project with the new values, filled by a form in a webpage. I know there is something wrong in my projectResource declaration, but I don't find what. Help !

Try this:
$resource('/api/projects', { id: projectId }, {
update: { method: 'PUT' }
});

$resource cannot make 'PUT' method, cuz of No 'Access-Control-Allow-Origin'. you can only found the 'OPTIONS' in the networks.In this case, you need to create your PUT call:
var data = $resource('someURL', { jobId: '#jobId'}, { 'update': { method:'PUT' }});
data.update(objectYouWannaUpdate);

Related

Angular $resource POSTing entire object, not just properties passed to it

I'm using Angular's $resource to interface with an API, and creating custom methods on that resource. One of these methods is a POST, and when I attempt to use it, it's sending the entire resource, not just the properties I'm attempting to post to the API. I don't think this is the intended behavior of the $resource service, but then, I might be missing something.
Here's the code:
The service:
angular.module('adminApp')
.factory('Framework', function($resource) {
return $resource('/api/frameworks/:id', {id: '#id'}, {
'update': {
method: 'PUT'
},
'getRequiredLicenses': {
method: 'GET',
url: '/api/frameworks/:id/required_licenses',
isArray: true
},
'addRequiredLicenses': {
method: 'POST',
url: '/api/frameworks/:id/required_licenses'
},
'removeRequiredLicense': {
method: 'DELETE',
url: '/api/frameworks/:id/required_licenses/:license_id'
}
});
});
Where I'm calling it:
scope.addLicensesToFramework = function() {
scope.framework.$addRequiredLicenses(null, {
required_licenses: Object.keys(scope.selectedLicenses) // returns an array of ints
});
}
(Note that this is in a directive. scope.framework is the instance of the framework resource)
When this request is sent, here's what's being included in the payload:
My intention is to only pass {'required_licenses': [12345,1236]} in the payload, and I can't seem to figure out why it's sending the entire resource as the body. (It's, in fact, not sending this at all, only the original resource)
Any insight would be really helpful, thanks!
Try calling it like this:
scope.addLicensesToFramework = function() {
scope.framework.$addRequiredLicenses({
required_licenses: Object.keys(scope.selectedLicenses),
id: 1234
}, function(resp){ console.log(resp) });
}
Also notice that I included the id in the parameters object.. you'll probably need that.

angular resource put request with array like params

I have to recreate the following url using angular resource, but i have been trying and can't do it:
my_domain/plan_memberships/24?access_token={{access_token}}&plan_membership[archived]=1
the problem is plan_membership[archived]=1
im only getting plan_membership=archived:1 and i can't seem to find a way to do it.
My resource is as follows:
.factory('deleteFromPlan', ['$resource', function ($resource){
return $resource(
angularConfig.rootApiEndpoint + '/me/plans/:plan_slug/plan_memberships/:membership_id',
{//param defaults
plan_slug: '#plan_slug',
token: '#access_token',
membership_id: '#membership_id',
plan_membership: '#plan_membership[archived]'
},
{
'update': {
method: 'PUT'
}
}
);
}])
and im using it like this:
deleteFromPlan.update({
access_token: $rootScope.angularConfig.user.access_token,
plan_slug: sharedVars.getPlanId(),
membership_id: membershipId,
plan_membership: { archived: 1 }},
function(data){
console.log(data);
spinner.hideActionLoader(overlay);
$scope.showOptionsModalMembers = false;
});
when i do this, i get this url:
http://localhost:3000/api/v1/me/plans/1/plan_memberships/10?plan_membership=%7B%22archived%22:1%7D&token=111111
when i should get this:
http://localhost:3000/api/v1/me/plans/1/plan_memberships/10?plan_membership[archived]=1&token=111111
Is there something else i need to do? also, its a PUT request
Thanks in advance!

how to get results of my webservice with jsonp?

I want to call one of my webservices via jsonp with angularjs.
When i call http://example.com/files?callback=JSON_CALLBACK directly in my browser, i got :
["folder1", "folder2"]
When i call from angularjs with :
$http.jsonp('http://example.com/files?callback=JSON_CALLBACK')
.success(function(data){
console.log(data);
$scope.folders = data;
});
console.log does not appear....
What am i doing wrong ?
Must my webservice return
JSON_CALLBACK(["folder1", "folder2"])
? Should i do it manually in my api ? browser don't do that automatically ?
What you are currently returning (["folder1", "folder2"]) is not valid JSONP. The JSON result must be wrapped by a javascript function call in order to be valid JSONP.
For example, when you use the URL like this:
http://example.com/files?callback=JSON_CALLBACK
Angular will replace the JSON_CALLBACK parameter with an angular function name (created internally), like:
http://example.com/files?callback=angular.callbacks._0
Your server would then need to be able to read that callback parameter and return the result like this:
angular.callbacks._0(["folder1", "folder2"]);
This is not an automatic mechanism, you need to implement that logic on your web server.
Try Using Following code snippet.
(function($) {
var url = 'http://example.com/files?callback=JSON_CALLBACK';
$.ajax({
type: 'GET',
url: url,
async: false,
jsonpCallback: 'jsonCallback',
contentType: "application/json",
dataType: 'jsonp',
success: function(data) {
console.dir(data);
},
error: function(e) {
console.log(e.message);
}
});
})(jQuery);
bmleite was right, I had to implement this logic on my API.
In my example, my server is made with Silex :
public function index()
{
$callback = $this->request->get('callback');
$files = $this->app['file.manager']->getList();
$response = new \Symfony\Component\HttpFoundation\JsonResponse();
$response->setData($files);
$response->setCallback($callback);
return $response;
}
And it works perfectly now. Thank you.

Angularjs $resource, how do I know which obj is being passed to it? URL not receiving :id

I am using a MEAN stack and I am a little confused on how the $resource works. I understand that the $resource factory is a service that retrieves data for controllers. However, I have two model objects, Compositions and Critiques. What I am trying to do is get critiques based off the url, which looks something like this: /compositions/:compositionId/review.
For some reason whenever I call
Reviews.query(function(review) {
console.log(review);
$scope.reviews= review;
});
I get this error:
GET localhost:3000/compositions/review 500 (Internal Server Error)
Here are my services:
angular.module('mean').factory('Reviews', ['$resource',
function($resource) {
return $resource('compositions/:docId/review', {
docId: '#docId'
},
{
update: {
method: 'PUT'
}
});
}
]);
angular.module('mean').factory('Compositions', ['$resource',
function($resource) {
return $resource('compositions/:compositionId', {
compositionId: '#_id'
},
{
update: {
method: 'PUT'
}
});
}
]);
The second one works if I navigate to /compositions/:compId, but the first one does not. Instead I get the error above. Why isn't the docId being passed in? Any ideas?
I want the compositionId, which is the docId in the 'critique' object models terms, but I want to get back critique objects. What am I doing wrong? Any help or advice is appreciated, thanks!
You are passing callback to query() - that is wrong. You should pass there a params object with your docId. This is how you should do that (in Angular 1.2)
Reviews.query({docId: 5}).$promise.then(function(review) {
console.log(review);
});

in Backbone, is it possible to tell fetch that it if it reads content that is content-type:'text/plain' to read it as JSON

I have a webserver that is sending back json files as 'text/plain'. I unfortunately can't adjust this. Can I tell a backbone fetch on a collection to read it as JSON even if it has this content/type? Like an emulateJSON for the response?
thx
Basically want to fix this:
Here's my backbone code that I'm having problems with (total backbone noob so I know there is most likely something wrong with how I'm handling this):
var MyItemList=Backbone.Collection.extend({url:'items.json', model:MyItem,
// not sure if I need this?
parse: function(response) {
return response.results;
}
});
var AppRouter=Backbone.Router.extend({
routes:{'':'list','detail/:id':'detail'},
list:function(){
var itemList=new MyItemList();
itemList.fetch({ dataType:'json',
error: function () {
console.log("error!!");
},
success: function () {
console.log("no error");
}
}).complete(function () {
console.log('done');
console.log('length1:' + itemList.length);
});
console.log('length2: '+ itemList.length);
}
my json:
Remove parse method:
With Parse:
Backbone uses jQuery.ajax under the hood for the ajax requests.
So you need to use the dataType: 'json' options to specify how jQuery should treat the response when you are calling fetch:
yourCollection.fetch({
dataType: 'json'
});

Resources