AngularJS resource: Send query parameter only if non-empty - angularjs

I have a Angularjs resource and in one of the methods, I want to send a query parameter to the backend if that query parameter is non-empty. Is it possible to achieve that without created a different method?
Example resource method:
get: {
method: 'GET',
url: /api/:token?source=:source,
paramSerializer: someSerializer
},
The code to call the method is,
myResource.get({token: '1234'}, {source: <some source>});
The token is required, but the source is optional, so sometimes it is not passed in to the call above. So if a value is provided for the source, I want to be able to send the source. If the source value is not provided, I want to not send the source at all. For instance, the call will become /api/1234 if source is empty, and the call will become /api/1234?source=some_source if the source is set as some_source.
With the code above, if the source is empty, I see that the request is '/api/1234?source=' when the source is empty.

Simply define the url template without the extra parameters:
get: {
method: 'GET',
url: "/api/:token",
},
Then add the extra parameters when invoking the action:
myResource.get({token: '1234', source: <some source>});
The extra parameters will be automatically added to the url as query parameters.
From the Docs:
Each key value in the parameter object is first bound to url template if present and then any excess keys are appended to the url search query after the ?.
For more information, see
AngularJS $resource API Reference - Arguments

If you pass query params via get.params{} then AngularJS will automatically handled stripping out undefined properties.

Related

$resource delete method passing params as query string

I am trying to implement CRUD using $resource, i am not finding any issues in POST, PUT and GET. But on delete method the params are getting passed as query string.
My service:
service.Assigndepart = $resource(CONFIG.wsurl + '/employee/assign/depart',null, {
update: {
method: 'PUT'
},
remove:{
method: 'DELETE'
}
});
And calling my controller as
Assigndepart.remove(params, function(success), function(error));
my url is passing with query string as ?employee=1234&depart=456.
Can some help on this
See basically if you get into the Html apis in form tag for method type what you will see is only support for get and post method, which indicates that with post and get we can do everything we want all of the others are just good conventions and some code optimizations(like put method).The delete method is just similar to the get method which always includes the parameters as its param there is nothing you can do about it.if you want to remove that you have to use the structure of post or put requests only or you can still use the delete method with some encryption and decryption at both ends i.e. application server and front end.
According to the Angular $resource documentation the action methods without a body need to be invoked with the following parameters:
Resource.action([parameters], postData, [success], [error])
So you are passing your postData as params for your DELETE action. The correct call on your controller will be:
Assigndepart.remove({}, params, function(success), function(error));

angular form submit get action append key value pairs

My goal was to have off a form submit for a get to be performed and as part of the uri, key value pairs appended like the following:
// GET /pets/42;q=11;r=22
Reading http://www.w3schools.com/tags/att_form_method.asp
description of form with setting form method to "get" I would have thought this was possible. In the world of angular, it seems like the expected behavior for a submit of a form results in post method. The controller can be written to generate any http verb but has the $http.get doesn't do what plain form get method would automatically and to generate a url like above, the controller would have to build the uri itself.
My apprehension of always using post off a form submit was the form in this case was part of a query/search action and not a data creation exercise. Maybe that's not the proper way to use form but has angular done away with automatically appended values from controls in key value pairs for a form with the $http.get service?
Of course you can do GET with query params in url.
The easiest way is to pass an object representing the key/value pairs to the params property of the $http config object.
var params = {q: 11, r:22};
$.get('/path/to/server/', {params: params}).then(....
Alternatively you can also create your own url string when you only have small number of params.
For further details read through the Usage section of $http docs

Backbone PUT request explicitly with out using id

I'm trying to PUT the data and my model doesn't have an id.
Is it possible to explicitly tell the Save() method to PUT the data irrespective of ID.
The save method has an options parameter that can override anything on the XHR:
model.save(newVals, { type: 'PUT' })
You can also override the isNew method. PUT vs POST is determined by the result of that method. You'll also want to make sure the URL is being created correctly for new and non-new objects.
Also consider setting the idAttribute correctly so that your model does have an id field that can be used to generate a correct url. Using POST and PUT correctly (POST new items, PUT updates to items) makes your api more intuitive.

Play 2.3/Angular JS $resource/routing issue

So I'm trying to AJAX a single solr doc from my results list to a "doc view" view. I'm trying to use AngularJS to AJAX to my view render method and display the doc that way, but I can't seem to get the angular to work and I'm not sure I'm doing things correctly on the Play side either. Would you at least be willing to tell me if what I'm trying to do will work? The Angular error comes from the docText.text(); call. Here is my code:
Angular controller code:
var docText = $resource("http://localhost:9000/views/full-doc-text.html", {
text: {method: 'PUT'}
});
$scope.handleViewText = function(value) {
docText.text({doc: value});
}
Java code:
public static Result viewText() {
JsonNode json = request().body().asJson();
//do stuff here
return ok(viewtext.render(json));
}
route:
GET /views/full-doc-text.html controllers.Application.viewText()
I see three problems with the code above;
1.The definition of docText resource is not correct. if your read the angularjs manual here you'll see that $resource has 4 parameters. First one is resource url, second is parameter defaults, third one is custom actions and forth one is resource options where last three of them are optional. In your code you pass custom actions as the second parameter, which should be the third. And since you don't have any parameters in your resource url second parameter must be null. So first correction is:
var docText = $resource("http://localhost:9000/views/full-doc-text.html", null, {
text: {method: 'PUT'}
});
2.You define your text action's HTTP method as PUT however in your routes file you are handling GET requests for your desired action. You should change your route definition as:
PUT /views/full-doc-text.html controllers.Application.viewText()
3.PUT method is usually used for update operations when implementing a RESTFULL service. In your case you don't seem to be updating anything. So I suggest to use POST method just for convention.

Restangular option to update an object without getting it from server

I have started using Restangular and it seems to be a very good library. However I have the following query. In order to update an object I am using the below code
Restangular.one("accounts", $scope.accountEdit.id).get().then(function(account) {
account = Restangular.copy($scope.accountEdit);
account.put();
});
In the above code I have to do a get request to the server and then update it. Is there a better way to just avoid the server call as I would like to update the object from my scope to the server.
you can use customPUT like this,
Restangular.one("accounts").customPUT($scope.accountEdit, $scope.accountEdit.id).then(function(account) {
TO-DO
});
customPUT([elem, path, params, headers]): Does a PUT to the specific
path. Optionally you can set params and headers and elem. Elem is the
element to post. If it's not set, it's assumed that it's the element
itself from which you're calling this function.
besides this you can extend your object with Restangular which gives you same result as your callback function did...
angular.extend($scope.accountEdit, Restangular.one("accounts", $scope.accountEdit.id));
$scope.accountEdit.put();

Resources