AngularJS Passing a list into $http.get() - javascript

I have a route on my server that is designed to handle a list of objects passed through a GET request. It does this by flattening fields of the same name.
For example:
GET http://example.com/services/echo?list=Hello&list=Stay&list=Goodbye
would be deserialized to a list containing ['Hello', 'Stay', 'Goodbye']
How would I replicate this behavior when using Angular's $http service? One way is to build the URI string manually. Another is to configure the servlet to deserialize the list from one field. But is there a cleaner way to do this, e.g. by using the config object?

This might work
$http({method: 'GET', url: '/someUrl',params:{list:['foo','bar']}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).

Related

<a href> Post request always returns to wrong URL Angular

Im trying to execute a like POST request with a in angular. The url gets filled in correctly as you can see
In the code it looks like this
But everytime it gives a 405 method not allowed (http://dressfriends.app) and returns to http://dressfriends.app
I do the exact samething with PHP without angular and this works
Anyone an idea?
Angular in not PHP. In order to solve this. you will need to use some service. Most popular are $http and $resource.
in case you choose $http service, you need to make
in somefile.html
in controller you will have something like this:
$scope.someFunction = function(){
$http.post(url, data, config)
.then(
function(response){
// success callback
},
function(response){
// failure callback
}
);
}
I recommend you to try to find tutorial for this like:
https://docs.angularjs.org/api/ng/service/$http
https://www.sitepoint.com/creating-crud-app-minutes-angulars-resource/
...

Angular & ASP.NET MVC - Parameter is null when I pass a parameter to my backend Controller

If you look at the parameter of my ASP.NET MVC Controller clientId, it's always null.
the only way i can get it to not be null and actually pass the data through successfully is to create a class... but that gets tedious and I can't create a class for every backend function i make just to get this to work.
Is there a way to pass data successfully without creating a class?
Thank you for any help
Angular Factory
PlaylistsFactory.getUsersForClient = function (clientId) {
return $http({
method: 'POST',
url: '/Show/GetUsersForClient',
data: JSON.stringify(clientId)
});
};
Angular Controller
PlaylistsFactory.getUsersForClient(clientId)
.success(function (userList) {
console.log('success!');
});
ASP.NET MVC Controller
public JsonResult GetUsersForClient(string clientId) //clientId is always null unless i create an object
{
...
}
Try making your JSON parameter match the name of your C# parameter as well as encasing that in the data payload as JSON:
return $http({
method: 'POST',
url: '/Show/GetUsersForClient',
data: {clientId: JSON.stringify(clientId)}
});
};
i would recommend that you follow the rules of a RESTful API.
This means you should use the HTTP verbs like GET (getting data), POST (updating data), PUT (creating data), DELETE (deleting data). See http://www.tutorialsteacher.com/mvc/actionverbs-in-mvc
Then you could also add the parameter you want to pass into the route of your API: /Show/GetUsersForClient/{clientId}. See http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx
In this case you disengage the problem of sending data in the body without having a ViewModel on the MVC-Controller side.
When you want to proceed with your solution, then try creating the Object before sending it:
PlaylistsFactory.getUsersForClient = function (clientId) {
var payload = { clientId: clientId }
return $http({
method: 'POST',
url: '/Show/GetUsersForClient',
data: payload
});
};
MVC / WebAPI also sometime choke when the content-type in the request header is text/plain or application/json. For example: a json-object will not be recognized properly by .Net when sent in text/plain.

Angular $http attach data as object

I'm trying to get list of tracks from soundcloud API with angularjs.
The parameters i'm trying to send are:
1) client_id (string)
2) duration (object with two properties).
Here's the code:
var CLIENT_ID = 'a81f01ef5d0036415431e8be76c8db0e';
var TRACKS_URL = 'https://api.soundcloud.com/tracks.json';
var app = angular.module('soundcloud', []);
app.controller('tracksController', function ($scope, $http) {
$http({
url: 'https://api.soundcloud.com/tracks.json',
method: 'GET',
data: {
client_id: CLIENT_ID,
duration: { // in milliseconds
from: 300000,
to: 400000
}
}
})
.success(function (data) {
$scope.trackList = data;
})
.error(function () { alert('error'); });
});
These parameters aren't recognized at all when I check the request in the broweser's debugger.
I tried to use 'params' instead of 'data', but this way it turns the 'duration' object to json --> then I get status 500 in response.
When I only send the client_id in params, it works fine because there's no object, only string.
jQuery's ajax method works fine: https://jsfiddle.net/oacwz1up/3/
What should I do ? How can I send the parameters normally ?
Help please! Thanks!
This happens because Angular serializes the request parameters differently than JQuery.
Angular 1.4 will address this problem introducing a paramSerializer property on the $http config object (and on $httpProvider.defaults). This can be used for arbitrarily serializing the requests parameters (for all or a particular request).
Note, that the feature is available only since v1.4.0-rc.0.
Besides the default serializer (which converts objects to JSON strings), there is an additional built-in serializer that emulates JQuery's param(): $httpParamSerializerJQLike.
You can use it like this:
$http.get(<API_URL>, {
params: {...},
paramSerializer: '$httpParamSerializerJQLike'
});
See, also, this short demo.
If you are using an older version of Angular, you could do one of the following:
Construct the whole URL (including the query string) yourself (possibly using an $http request interceptor to automatically apply this to all requests).
Keep the params in a flat format that will result in Angular's serializing them as expected:
var REQ_PARAMS = {
client_id: 'a81f01ef5d0036415431e8be76c8db0e',
'duration[from]': 200000,
'duration[to]': 205000
};
If you look at $http documentation, on request it applies a default transformation which is $http.defaults.transformRequest and as described will do the following (as you saw) :
If the data property of the request configuration object contains an object, serialize it into JSON format.
What you need to do is override this function by specifying your own transformRequest object.
function appendTransform(defaults, transform) {
// We can't guarantee that the default transformation is an array
defaults = angular.isArray(defaults) ? defaults : [defaults];
// Append the new transformation to the defaults
return defaults.concat(transform);
}
$http({
url: '...',
method: 'GET',
transformResponse: appendTransform($http.defaults.transformResponse, function(value) {
return doTransform(value);
})
});
You need to find a way to get the same syntax as jQuery provide which is :
https://api.soundcloud.com/tracks.json?client_id=a81f01ef5d0036415431e8be76c8db0e&duration[from]=200000&duration[to]=205000
Use a condition is is an object and generate manually your String. Should not be difficult.
that's a strange API - I don't know why they don't do something like "duration_from" rather than requiring duration[from] - as suggested you could certainly transform the request, but if this is just a one off you could also try simply hard-coding it using url escaped values for [ and ]:
var dataToSend = {
client_id: 'a81f01ef5d0036415431e8be76c8db0e',
'duration%5Bfrom%5D': 200000,
'duration%5Bto%5D': 205000
};
$http.get('http://api.soundcloud.com/tracks.json', {params:dataToSend});
The params property is way to transform query in restful way. Just transform data in dataToSend object, and it will work.
This is a URL that should be created:
https://api.soundcloud.com/tracks.json?client_id=a81f01ef5d0036415431e8be76c8db0e&duration%5Bfrom%5D=200000&duration%5Bto%5D=205000

transform request data with resource service in angular

I'm trying to send just the array of my data to the server. I found this post discussing how to send an array, but I can't get it to work.
AngularJS: ngResource and array of object as params to URL
The problem I am having is my resource gets sent back to me as JSON like this
{
Results: []
}
So when I ask for my resources,
var collaboratorResource = api.CollaboratorList.get({Id: Id });
but then, if I try something like
collaboratorResource.$save($scope.collaborators);
When I look at firebug, it shows that my data is being sent as
{
Results: []
}
when in reality, I don't want to send the data as an object with the array as a Results property. I want to send it just as an array []. I need to do that since the api is legacy and expects that.
I've been trying to see if transformRequest works, like if I did
collaboratorResource.$save({data: $scope.collaborators, transformRequest: function (data, headers) { return data.results; }});
collaboratorResource.$save({}, $scope.collaborators);
collaboratorResource.$save($scope.collaborators);
But that doesn't seem to work either. Is this even possible? As an aside, if I use $http like this, it works:
$http({ method: "POST", data: $scope.collaborators, url: collaboratorUrl });
I'm just not sure how to use the $resource service properly since I'd prefer to wrap everything in $resource if possible and not have a hybrid of both if possible. Thanks.

should I return the entire record again as a response from server to a POST when I do $update on an angular resource?

In my factory
return $resource('rest/records/:id', {}, {
query: {
method: 'GET',
isArray: true,
// RestSQL has an extra struct around the array
transformResponse: function(data) {
return angular.fromJson(data).records;
}
},
create: { method: 'POST' },
update: { method: 'PUT', params: {id: '#id'},
});
Which is used by a service which is in turn used by a controller.
I get the correct record in the controller.
Then when I edit and want to save the record
I do record.$update();
my rest POST is successful as I get a valid response from server.
But the response from server is just some kind of success message e.g. "{ "number": 2 }".
Now I have an angular template which uses this records properties e.g. {{record.image}}
But as soon as I do record.$update();
records properties disapper and record now simply looks like
record = {"number" : 2}
So should I return the entire record as a response to the POST action or should I update in some other fashion so as to the record doesnt get its properties overwritten by the response from server?
A temporary way of getting around this of course is
$scope.temp = jQuery.extend(true, {}, $scope.record);
$scope.temp.$update();
I am returning the updated object on POST's, PUT's etc. (see also this: Should a RESTful 'PUT' operation return something) all the time. So,
no problem with always returning the updated object in the response
don't use tricks and more code to sove a problem that can be solved by applying a very simple solution (in this case, returning the updated object). I love those fixes: Simple solution, problem solved and code removed instead of adding things here and padding things there etc., making code unreadable und unnecessarily complex.

Categories

Resources