Join the Stack Overflow Community
Stack Overflow is a community of 6.8 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

As the title suggests, I am attempting to write an AJAX call using Angular's $http object. I would like to send a post request that submits JSON in the body of the request, but also has a query string appended to the URL. After reading the documentation for $http all the way through, surfing for answers on SO, and attempting several different configurations, I am still not clear on how to pass the parameters correctly. Currently, my API responds with either empty JSON or Bad Request (400).

Code

function inviteStaff (json) {
    authToken = service.getAuthToken();
    return $http({
        method: 'POST',
        url: baseUrl + '/invitations' + '?authToken=' + authToken,
        data: JSON.stringify(json),
        headers: {
            'Content-type': 'application/json'
        }
    });
}

Consuming Function

self.invite = function ($form) {
    self.showLoader = true;
    InvitesService.inviteStaff($scope.inviteModel).then(function () {
        $form.$setPristine();
        $scope.inviteModel.timestamp = new Date();
        $scope.invites.unshift($scope.inviteModel);
        $scope.inviteModel = self.createNewInvite();
        self.showLoader = false;
    }, 
    function () {
       self.showLoader = false;
    });
};

Request log

data: "authToken=********&t=*****" // this is weird because it adds another "t" parameter to this query string here 
headers: Object
    Accept: "application/json"
    Accept-Language: "en"
    Content-type: "application/json"
    authToken: "*********" // just the token here
    __proto__: Object
method: "POST"
params: Object
timeout: Object
transformRequest: Array[1]
transformResponse: Array[1]
url: "http://****.****.com:****/doctors/invitations?authToken=*****"
__proto__: Object

Param JSON object

{
    accountType: "LEAD_DOCTOR", 
    firstName: "kraken", 
    lastName: "lastName", 
    email: "[email protected]"
}

Can anyone shed a little light on how this should work? Do I pass the json object to data or params? Do I need to use JSON.stringify on the data field? In some cases, I also saw people passing an empty string to data.

I also have been running it through Charles Proxy. I can get very close to what I want, but for some reason the JSON is showing under the JSON Text filter as a query string, and not the JSON filter.

Any ideas would be helpful. I will be refactoring and upgrading it all to use the $resource tool, but we are on a tight deadline and I just want to get this working for now. Let me know if you need more info.

UPDATE We're using swagger to document our API, and you can actually hit the endpoint in their UI. It produces the following CURL command. I thought it might help spot the issue.

curl -X POST --header "Content-Type: application/json" --header "Accept: application/json" -d "{
    \"firstName\": \"string\",
    \"lastName\": \"string\",
    \"email\": \"[email protected]\",
    \"accountType\": \"CLIENT\"
}" "http://*****.****.com:****/doctors/invitations?authToken=***obfuscatedAuthToken***"
share|improve this question
1  
what exactly is the problem here? – M B Mar 22 '16 at 14:28
1  
Second question: you can pass the whole javascript object, Angular will handle it – dex Mar 22 '16 at 14:29
    
@MB I will update the question – Kraken Mar 22 '16 at 14:30
1  
using data is correct, params is used for variables and data for an object. You do not have to do anything to your object just pass it as is – M B Mar 22 '16 at 14:33
    
where are you passing it to? could be you are accepting it wrong on the API side? – M B Mar 22 '16 at 14:35

I would recommend you to take advantage of the header field:

function inviteStaff (json) {
authToken = service.getAuthToken();
return $http({
    method: 'POST',
    url: baseUrl + '/invitations',
    data: JSON.stringify(json),
    headers: {
        'Content-type': 'application/json',
        'authToken': authToken
    }
   });
 }

Then on the server side, ask the current request for the header value of authToken.

Passing Tokens in the URL has some security concerns, for your reading: https URL with token parameter : how secure is it?

share|improve this answer
    
"we are on a tight deadline and I just want to get this working for now" -- Your suggestion is valid, but not what the OP is looking for atm. – Brett Mar 22 '16 at 14:48
    
@Brett was right on the nose. Very helpful advice for the future, though. Thanks! We are actually already planning to tighten up security in the near future. – Kraken Mar 26 '16 at 13:28
up vote 0 down vote accepted

It turns out we had an HTTP Interceptor function elsewhere in the codebase that was changing the content-type! Wrapped that in a conditional, and it is good to go now. Thanks to everyone who helped me ensure my code was written correctly!

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.