How to use esri.request to post JSON?

7305
9
06-07-2017 05:06 PM
NavanJohnson
New Contributor II

I have been using the esri.request to make get calls for a while and it's worked great:

request = Request({url: url, handleAs: 'json'});

Now I have a requirement to be able to post JSON data and get a similar response. From the API reference I thought it would be as simple as:

request = Request({url: url, handleAs: 'json', callbackParamName: 'callback', content: params}, {usePost: 'true'});

But I was getting a 415 error from the REST endpoint I was hitting.

I looked at the developer tools, Network section, and I saw that under Params, the payload was of type Form data. I think it needs to be JSON format. I looked under Headers and Content-Type is "application/x-www-form-urlencoded".

So I found the setRequestPreCallback function and started using that to set the headers["Content-Type"] = "application/json". That seemed to work because I can see Content-Type is now "application/json". However, my 415 error changed to a 400 error. If I look under Params it is not type JSON like I expect. It just says Request payload and the data looks like a string with = and & instead of a JSON format.

Is there something else you have to do to make the data post as JSON?

Tags (3)
9 Replies
ThomasSolow
Occasional Contributor III

Try { ..., content:JSON.stringify(params), ... }

It may be interpreting your params as FormData or something along those lines.

NavanJohnson
New Contributor II

Yeah, I did try that, and under Params it still says Request payload and the value looks like:

0=%7B&1=%22&2=s&3=y&4=s&5=_&6=a&7=s&8....

I even tried to just hard code the content like:

request = Request({url: url, handleAs: 'json', callbackParamName: 'callback', content: {username: "test", role: "user"}}, {usePost: 'true'});

And I still get a Request payload that looks like:

username=test&role=user

0 Kudos
FC_Basson
MVP Regular Contributor

Have you tried JSON.stringify on the individual JSON-format parameters in the request content?  And also throw in a f: "json" in the content.

0 Kudos
NavanJohnson
New Contributor II

Do you mean like this?

request = Request({url: url, handleAs: 'json', callbackParamName: 'callback', content: {f: "json", username: JSON.stringify("test"), role: JSON.stringify("user")}}, {usePost: 'true'});

That creates a Request payload of:

f=json&username=%22test%22&role=%22user%22

It still doesn't look like JSON and still gives status 400.

0 Kudos
FC_Basson
MVP Regular Contributor

Yes that's the idea, but only for more complex content parameters that are also JSON objects.  Why not try the request with a jQuery Ajax or standard XMLHttpRequest instead?

NavanJohnson
New Contributor II

Yeah, that's what I am doing for now. The $.ajax works as expected. I just wanted to use pure esri if I could. It seems like something that is supposed to work and I am just missing something. Thanks.

JohnGrayson
Esri Regular Contributor

In the Network tab, can you see if the request is being made as GET or POST?  If it still uses GET, one suggestion is to try using a boolean instead of a string for the 'usePost' parameter.  It also helps if you have a JSBin or similar so we can see the code and issue in action.

{usePost:true}
FC_Basson
MVP Regular Contributor

I would also like to see how the esri.request compares to the jQuery Ajax request.

0 Kudos
LefterisKoumis
Occasional Contributor III

Look at the code under the folder named "editors" of the ESRI's geoprocessing widget. You will see how they handle post with url or files (csv, shapefiles)....