How to pass nested parameters using angular - javascript

I am trying to send a get request to my rails backend using angular. So what am looking for is the request like this
Parameters: {"location"=>"london", "q"=>{"price_gteq":"33333", "price_lteq":"7777"}}
So in my app.js I tried below code to send the request with the parameters. I am now getting unexpected / and the second nested parameter is not showing aswell as seen below.
$http({
url: "/search.json",
method: "GET",
params: {location: $scope.searchLocation, q: {price_gteq: $scope.min_price, price_lteq: $scope.max_price} }
})
This is what i get when I try like above
Parameters: {"location"=>"london", "q"=>"{\"price_gteq\":\"33333\"}"}
Could someone tell me what am doing wrong here??

By default angular uses $httpParamSerializer which actually can handle nested parameters. Check if your $http uses this service. If for some reason it doesn't work, you can write own paramSerializer and pass it into $http configuration object.
Also check if price_lteq present at the moment, when you send request.

Related

Get jQuery $.ajax to send data in body for GET [duplicate]

The service API I am consuming has a given GET method that requires the data be sent in the body of the request.
The data required in the body is a list of id's separated by hypen and could potentially be very large and thus it must be sent in the body otherwise it will likely foobar somewhere in the browsers/proxies/webservers etc chain. Note I don't have control over the service or API so please don't make suggestions to change it.
I am using the following jQuery code however observing the request/response in fiddler I can see that the "data" I am sending is ALWAYS converted and appended to the query string despite me setting the "processData" option to false...
$.ajax({
url: "htttp://api.com/entity/list($body)",
type: "GET",
data: "id1-id2-id3",
contentType: "text/plain",
dataType: "json",
processData: false, // avoid the data being parsed to query string params
success: onSuccess,
error: onError
});
Anyone know how I can force the "data" value to be sent in the body of the request?
In general, that's not how systems use GET requests. So, it will be hard to get your libraries to play along. In fact, the spec says that "If the request method is a case-sensitive match for GET or HEAD act as if data is null." So, I think you are out of luck unless the browser you are using doesn't respect that part of the spec.
You can probably setup an endpoint on your own server for a POST ajax request, then redirect that in your server code to a GET request with a body.
If you aren't absolutely tied to GET requests with the body being the data, you have two options.
POST with data: This is probably what you want. If you are passing data along, that probably means you are modifying some model or performing some action on the server. These types of actions are typically done with POST requests.
GET with query string data: You can convert your data to query string parameters and pass them along to the server that way.
url: 'somesite.com/models/thing?ids=1,2,3'
we all know generally that for sending the data according to the http standards we generally use POST request.
But if you really want to use Get for sending the data in your scenario
I would suggest you to use the query-string or query-parameters.
1.GET use of Query string as.
{{url}}admin/recordings/some_id
here the some_id is mendatory parameter to send and can be used and req.params.some_id at server side.
2.GET use of query string as{{url}}admin/recordings?durationExact=34&isFavourite=true
here the durationExact ,isFavourite is optional strings to send and can be used and req.query.durationExact and req.query.isFavourite at server side.
3.GET Sending arrays
{{url}}admin/recordings/sessions/?os["Windows","Linux","Macintosh"]
and you can access those array values at server side like this
let osValues = JSON.parse(req.query.os);
if(osValues.length > 0)
{
for (let i=0; i<osValues.length; i++)
{
console.log(osValues[i])
//do whatever you want to do here
}
}
Just in case somebody ist still coming along this question:
There is a body query object in any request. You do not need to parse it yourself.
E.g. if you want to send an accessToken from a client with GET, you could do it like this:
const request = require('superagent');
request.get(`http://localhost:3000/download?accessToken=${accessToken}`).end((err, res) => {
if (err) throw new Error(err);
console.log(res);
});
The server request object then looks like {request: { ... query: { accessToken: abcfed } ... } }
You know, I have a not so standard way around this. I typically use nextjs. I like to make things restful if at all possible. If I need to make a get request I instead use post and in the body I add a submethod parameter which is GET. At which point my server side handles it. I know it's still a post method technically but this makes the intention clear and I don't need to add any query parameters. Then the get method handles a get request using the data provided in the post method. Hopefully this helps. It's a bit of a side step around proper protocol but it does mean there's no crazy work around and the code on the server side can handle it without any problems. The first thing present in the server side is if(subMethod === "GET"){|DO WHATEVER YOU NEED|}

Expected response to contain an object but got an array error in angular js

Hi i have tried creating a simple sign in service, but ended up with this error.
My service
foodModule.factory('Login', function($resource){
return $resource('http://localhost:1337/User/', {}, {
});
});
my fucntion
$scope.signIn=function(){
console.log('Sign in function works');
console.log($scope.user.signemail);
console.log($scope.user.signpassword);
$scope.signuser=Login.get({email:$scope.user.signemail,password:$scope.user.signpassword});
console.log($scope.signuser);
}
Error:
Error: [$resource:badcfg] http://errors.angularjs.org/1.3.15/$resource/badcfg?p0=get&p1=object&p2=array
Am i doing anything wrong here? I hope i should mention the method properly, any idea on this error??
resource get should return a single object, but in your case, an array is being returned.
The problem could be that you are trying to do login using GET. Normally login is achieved using http POST. Most probably you should use Login.post instead of Login.get
The parameters of $resources are as resource(url, paramDefaults, actions).
In first you already have url and blank paramDefaults are acceptable but in last parameters you need to specify explictly isArray: false .
So action can be like:-
'query': {method: 'GET', isArray: false }
Hope it helps :)
Make sure your $resource configuration matches the actual format of the data returned from the server.
For more information: https://docs.angularjs.org/api/ngResource/service/$resource

Using POST and GET to Exchange Data Through Endpoints

I'm attempting to build a web app using Spotify's web API however, I find their tutorial lacking. The way it works is data is requested using POST and GET functionality and sent back using JSON. Seems easy enough, want to get information about an artist? Just call GET https://api.spotify.com/v1/artists/0OdUWJ0sBjDrqHygGUXeCF and you get a nice JSON document with information about the requested artist.
The problem is I don't know how to make that GET call. jQuery has get and post methods both with "data" parameters but I'm not sure on the syntax necessary, especially when it comes to exchanging an authorization code for an access token. If you visit Spotify's authorization guide and scroll to step 4 of the Authorization Code Flow you can see I need to make a POST call to https://accounts.spotify.com/api/token. The call must have 3 request body parameters and 1 header parameter and upon succession a JSON file with the appropriate data is in the response body.
My question is how do I make POST and GET calls that have body parameters and header parameters and how do I extract the JSON data from the response body after a successful call?
As you can see from their code examples & libraries and this jsFiddle, their getUserData request is nothing but a simple ajax call, which contains their url and a headers object (which contains a prefix string concatenated with the accessToken) as parameters:
function getUserData(accessToken) {
return $.ajax({
url: 'https://api.spotify.com/v1/me',
headers: {
'Authorization': 'Bearer ' + accessToken
}
});
}
Generally, when you need to pass parameters in an $.ajax call, just do as shown above, or construct an object first and include it like this:
YourObj = {
url: "your url here",
param2: "param val 2",
param3: "param val 3",
...
}
$.ajax(YourObj).done(function(data){
//do something with the returned data here, e.g.
console.log("data: ", data);
});
This approach can be useful if your parameters are dependent on other values which are not so readily avalable.

Use angularjs to post JSON without a parameter name

Currently I have a resource like so:
return $resource(usersUrl, {}, {
//The data model is loaded via a GET request to the app
query: {method: 'GET', params: {}, isArray: false},
putupdate: {method: 'PUT', params:{}}
});
Now I would like to put some JSON that looks like:
{"providerid":"userpass","firstname":"t","lastname":"b","fullname":"t b","email":"emailaddress,"avatarurl":"http:/.....","passwordset":true}
Anyway as you can see it doesn't have a top level name, if I pass this information in as a parameter to the resource a name is appended to the json like:
myparam:{"providerid":"userpass","firstname":"t","lastname":"b","fullname":"t b","email":"emailaddress,"avatarurl":"http:/.....","passwordset":true}
Is there a away of preventing this from happening as the server side doesn't like it?
Thanks
Tom
From your question it sounds like you are trying to use $resource to post some arbitrary json data. If this data is not a Resource() you should simply use $http.
$http.put(theUrl, theJsonData);
If it is actually a Resource() you can just call the method you declared when building your resource.
myResource.putupdate();

Error when calling webservice with jquery

I have read a lot about jquery and i have a webservice where i convert a companyID to the real companyName. Now i want to call that webservice with jquery or javascript. The webservice is on host http://webservice/service.asmx en i'm working on http://tlmos. I don't work and i always get an error
Here is my code:
<script type="text/javascript" src="http://kmosvi24/_layouts/jquery-1.3.2.min.js"></script>
<script type="text/javascript">
var test = "KBEACDNV";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://webservice/service.asmx/getCompanyByCompanyID",
data: "{'sCompanyID:' + 'test'}",
dataType: "json",
succes:function(response){ alert("good"); },
error: function(response) { alert("Uh oh"); },
complete: function(response) { alert("" + response); }
});
</script>
Can someone help me?
thx
Umm.. you spelled success wrong on line 11
.. and you probably want to format your data as
data: "sCompanyID=test"
Take a quick pass through the jQuery API page on this one to verify you are passing the parameters that your service expects. It looks like you are expecting a SOAP packet with an ASMX service, and jQuery is more suited to hitting a restful service generated from an ASHX file or WCF service.
You can make a request to a different server, but only if the call uses GET. Since all you do is lookup anyway, a GET request should be fine.
As some othe people have pointed out you cannot call a webservice on another domain, however as you are using ASP.NET, you can write a raw HTTP handler (normally with an .ashx extension to proxy your request from client to server.) Which you'd place on your "timos" server
so in your ashx file you can write something along the lines of...
public void ProcessRequest (HttpContext context)
{
XmlDocument wsResponse = new XmlDocument();
string url = "http://webservice/service.asmx/getCompanyByCompanyID?CompanyID="
context.Request.Form["CompanyID"].ToString()
wsResponse.Load(url);
string XMLDocument = wsResponse.InnerXml;
context.Response.ContentType = "text/xml";
context.Response.Write(XMLDocument);
}
Hope this helps.
You can't do AJAX calls to hosts other than your own. If you really have to do this make a call to your own server and use a simple proxy to redirect to the domain you need.
You could do this for example by using a ProxyPass-directive in your webserver:
ProxyPass /service/ http://webservice/service.asmx
ProxyPassReverse /service/ http://webservice/service.asmx
Then you can issue an AJAX-request to /service/getCompanyByCompanyID and it will be proxied to the correct URL.
I don't think you are using the data parameter right, usually it's a key-value pair like:
data: {sCompanyID: 'test'}
I believe that they way you are using it will result in jQuery attempting to post to http://webservice/service.asmx/getCompanyByCompanyID?sCompanyID:blah
Also aren't .NET web services SOAP? I don't think jQuery can parse that...
edit: Nevermind, didn't realize you were passing these as json data. Thanks commenters!
In order to run your web-services from Jquery, you should use either WCF or just usual web services, but you should add [ScriptMethod] to your service's method and [ScriptService] to your webservice description.
Wow wow
just noticed that you're trying to call the service from one host to another... that one won't work. service should be hosted on the same domain as the page where it's being called from.
as a reply to Jeff's answer, correct way to format data is data: {key: "value"}
With jQuery Ajax Requests you need to use the following format when defining the variables to be sent in the request:
data: "variableName=variableContent",
You wrote:
data: "{'sCompanyID:' + 'test'}"
This won't work for two reasons:
- You have included curly brackets which don't need to be there.
- You have used a semi-colon,":", instead of an equals sign,"=".
So long as you change these it should work.
P.S I only just realized that Jeff Fritz has already given you the right answer. His answer is spot on!

Categories