Fetch Angular $http response header param - angularjs

I am working on an Progressive Web app module with AngularJS.
I have made a network call with POST request using '$http', I am able to get a response of it but am not getting 'Response Header' params.
Here is my Response header:
Connection:keep-alive
Content-Type:application/json
Date:Fri, 19 May 2017 10:41:49 GMT
Server:JBoss-EAP/7
Session-ID:XXXXX-YYYY-ZZZ
Transfer-Encoding:chunked
X-Powered-By:Undertow/1
And below is a request and API call.
$scope.data = {userid: $scope.username,
os: 'android',
device_id: 'b0316b93ae786ec0',
source: 'iv2',
password: $scope.password,
build_version_code: '2.3',
version: '5.1.1'};
$http({
method : "POST",
url: 'https://domain.name/v1/users/login',
data : $scope.data,
headers: {
'content-type': "application/json",
'sessionID': ''
}
})
.then(function successcallback(response){
console.log("Session-ID" , response.headers());
console.log("response" , response);
}, function errorcallback(response){
console.log('error' , response);
});
I have tried below possible solution based on response callback method.
function successcallback(response){
response.header('Session-ID');
}
and
success(function(response , status , headers , config){
console.log("response" ," headers - " + headers('Session-ID'));
}
The both approaches returns a null value instead of expected value.
Please let me know if I am missing something. I am happy to get all possible help.

Related

$http - post - Bad request error not handled (undefined)

I am trying to do a POST to create an account and I am expecting a 400 Bad Request (Username already used or Email already used).
I have confirmed with other tools (RESTED for firefox) that I am receiving the correct 400 Error with my message, but with AngularJS response.status, response.data and response.statusText all give an 'undefined' value.
Below is the definition of my request in AngularJS:
var req = {
method: 'POST',
url: myURL,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
data: $scope.user
};
$http(req).then(
function(response){
console.log("account created perfectly!");
},
function(response){
console.log("ERROR " + response.status + ": account cannot be created!");
// the data is Username/Password
alert(response.data + " invalid!");
}
)
What am I doing wrong?
Can you post your inspector screenshot here?
Looks like there is some issue with the passing of request body.
The 4xx error comes when the client sends a bad request.
Also, for your use case, return status code 2xx as this is the valid business case and it should not be 4xX.

CORS post call not working in Angularjs

I am trying to implement cross-origin post call from angularjs application, then I get the following error.
Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
But, when I make a Ajax call it works properly.
How HTTP post call work in angularjs?
Ajax call
$.ajax({
type: 'POST',
url: getAccessTokenUrl,
data: JSON.stringify(clintdata),
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function(resultData) {
console.log(resultData);
},
error: function (request, status, error) {
console.log(status);
}
});
Angularjs HTTP call
$http({
method: 'POST',
url: getAccessTokenUrl,
data: clientdata,
headers: {
'Authorization': undefined,
'Auth-Token': undefined
}
}).then(function(res){
console.log(res);
}, function(err){
console.log(err);
});
I have some default setting. Authorization is for others REST
$http.defaults.headers.common['Content-Type'] = 'application/json;charset=utf-8;' ;
$http.defaults.headers.common['Auth-Token'] = 'X-Requested-With';
$http.defaults.headers.common['Authorization'] = $('#Authorization').val();
Access-Control-* headers are response headers. They come from the server in response to a request. You do not apply them to your request headers.
If your jQuery request works correctly without adding any additional headers, then your AngularJS request should work the same.
The equivalent jQuery request in AngularJS (including removing the Authorization and Auth-Token headers you've set via defaults) is
$http.post(getAccessTokenUrl, clientdata, {
headers: {
Authorization: undefined,
'Auth-Token': undefined
}
}).then(response => {
console.log(response.data)
})
or the long version
$http({
method: 'POST',
url: getAccessTokenUrl,
data: clientdata,
headers: {
Authorization: undefined,
'Auth-Token': undefined
}
}).then(...)
AngularJS by default...
POSTS requests as application/json content-type
Serializes the data property to JSON
Expects a JSON response
Resolves the $http promise with a response object with the response body parsed as JSON into the data property
Remove the following setting
$http.defaults.headers.common['Auth-Token'] = 'X-Requested-With';
$http.defaults.headers.common['Authorization'] = $('#Authorization').val();
Add Authorization header dynamically from Interceptor
request: function(config) {
if (angular.isUndefined(config.skipInterceptor) || !config.skipInterceptor) {
// add Authorization token
}
return config;
}
Http call like this
$http.post('your url', {
skipInterceptor: true
})

I am trying to upload a file to Django server using angularjs 1.6.5. I am not able to upload file using $http.patch method

Using Angularjs 1.6.5 I am trying to upload a file to the Django server. When I try to upload the file I am not sure what type of 'Content-Type' header should be passed with the $http.patch method. Here is the following my Angular apps config:-
var app = angular.module("edit_modules", []);
app.config(function($httpProvider) {
$httpProvider.defaults.xsrfCookieName = 'csrftoken';
$httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
$httpProvider.defaults.headers.common['Content-Type'] = 'application/json; charset=utf-8';
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.headers.common['Accept'] = 'application/json, text/javascript';
});
And this is my patch method:-
$http.patch(url, data, {
headers: {'Content-Type': 'application/json; charset=utf-8' }
}).then(successCallback, errorCallback);
function successCallback(response){
console.log("Success");
console.log(response);
};
function errorCallback(error){
alert("Error Uploading!");
console.log(error);
};
When I pass {'Content-Type': 'application/json; charset=utf-8' } through the Header I get the following error:-
"The submitted data was not a file. Check the encoding type on the form."
Status :- 400
Since its content-type is file I used the following header {'Content-Type': 'multipart/form-data; charset=utf-8'} . But then I got this error:-
Multipart form parse error - Invalid boundary in multipart: None
Status :- 400
As suggested in the link here I tried the following header as well {'Content-Type': undefined} But this as well did not resolve my problem and I got the following error:-
Unsupported media type "text/plain;charset=UTF-8" in request.
Status :- 415
However when I tried with simple text fields the PATCH method worked with the header supplied being {'Content-Type': 'application/json; charset=utf-8' }. I am not sure where the problem is. I even tried to see the console for what data was being set to be patched
data = {
"video": element.files[0]
};
console.log(data);
THIS is what i got on console:-
{video: File(99861)}video: File(99861) {name: "Capture2.PNG", lastModified: 1517491665223, lastModifiedDate: Thu Feb 01 2018 18:57:45 GMT+0530 (India Standard Time), webkitRelativePath: "", size: 99861, …}
any help is much appreciated.
Referring to the answer here I found that you need to attach the File Object to be sent using FormData. Also you need an additional header in config transformRequest: angular.identity,. Here is the successful PATCH method that worked for me.
var fd = new FormData();
fd.append('video', element.files[0]);
$http.patch(url, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).then(successCallback, errorCallback);
function successCallback(response){
console.log("Success");
console.log(response);
};
function errorCallback(error){
alert("Error Uploading!");
console.log(error);
};
In the second line 'video' is the REST API Endpoint's variable where my file will be stored. In order to avoid the error
Multipart form parse error - Invalid boundary in multipart: None
I have left the headers: {'Content-Type': undefined}.

$http GET request not reaching server from AngularJS app

I have a REST API deployed on localhost with the following GET endpoint: localhost:9000/get-events/1
This endpoint is returning the correct response when I send the request through Postman or through a web browser. It also contains CORS headers etc, and I have also handled the options requests with appropriate headers. (The server is implemented in Play Framework).
The response from Postman for the above GET request is:
headers:
Access-Control-Allow-Origin →*
Content-Length →34
Content-Security-Policy →default-src 'self'
Content-Type →application/json
Date →Tue, 10 Apr 2018 04:50:16 GMT
Referrer-Policy →origin-when-cross-origin, strict-origin-when-cross-origin
X-Content-Type-Options →nosniff
X-Frame-Options →DENY
X-Permitted-Cross-Domain-Policies →master-only
X-XSS-Protection →1; mode=block
body:
{
"status": "success",
"events": "[<some list....>]"
}
I basically want the list that is being returned by the server to be loaded in a ng-repeat list in my Event List page when the user is navigating to it. I have implemented this in my code like this:
inside the controller in app.js:
$scope.getlist = function() {
$http({
url: 'localhost:9000/get-events/1',
method: 'GET'
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
$scope.events = JSON.parse(response.data.events);
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}
and in the front end, index.html:
Fetch List
and, eventList.html:
<ul>
<li data-ng-repeat="event in events">{{event.name}}</li>
</ul>
When I click on the link, it gives the following error in the browser's console:
ERROR: {"data":null,"status":-1,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"localhost:9000/get-events/1","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":""}
from the server logs, it seems that the request is not reaching the server at all.
The strange thing is that I am also sending a POST request to the same server, while doing the user login and that request is successfully reaching the server and correctly giving the response from the angularJS app.
This is how I call the POST from my angularjs controller:
$scope.login = function () {
console.log('login called');
var loginURL = 'localhost:9000/login';
var loginInfo = {
'email': $scope.email,
'password': $scope.password
};
$http({
url: loginURL,
method: 'POST',
data: loginInfo,
headers: { 'Content-Type': 'application/json' }
}).then(function successLogin(response) {
console.log('SUCCESS: ' + JSON.stringify(response));
}, function failLogin(response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}
What am I missing while doing the GET request?
In the server have you added CORS header Access-Control-Allow-Origin in server end ?
Its Working for me
try this.
html:
<a ng-click="getlist()">Fetch List</a>
js:
$scope.getlist = function () {
$http({
url: 'ControllerName/getevents/1',
method: 'GET'
}).then(function (response) {
console.log('SUCCESS: ' + JSON.stringify(response));
}, function (response) {
console.log('ERROR: ' + JSON.stringify(response));
});
}
output in console:
SUCCESS: {"data":"","status":200,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"Employee/getevents/1","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":"OK","xhrStatus":"complete"}
So, I was running my Angular App using Firefox earlier and I just thought of using Google Chrome. It helped me by providing this extra information in the console:
Failed to load localhost:9000/volunteer-events/1: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
So, it seems that in the HTTP get URL I was just using localhost:9000... instead of the complete http://localhost:9000...
changing my URL to http://localhost:9000... fixed the problem.
Answering this here so that anyone else who was stuck on this for long time like me would benefit from it!
Although I am still not sure how it worked for the POST ?

AngularJS HTTP GET request returning cached data

In my AngularJS app I am sending HTTP GET request as below.
MyService.HttpReq("testUrl", "GET", null);
HttpReq Method is defined in a service and implemented as below:
this.HttpReq = function(URL, method, payload)
{
$http({
url: URL,
method: method,
cache: false,
data: postData,
headers: {
'Content-Type': 'application/json',
}
}).success(function(response)
{
console.log("Success: "+JSON.stringify(response));
}).error(function(data, status)
{
console.error("Error");
});
}
First of all is this the right way of sending HTTP request in AngularJS?
The problem that I am facing is, some times I get cached data as response and HTTP request is not hitting the server. what can be the issue?
UPDATE
As per the comment and answer I have updated my HTTP request code as below, but still getting same issue.
this.HttpReq = function(URL, method, payload)
{
$http({
url: URL,
method: method,
cache: false,
data: payload,
headers: {
'Content-Type': 'application/json',
'Cache-Control' : 'no-cache'
}
}).
then(
function(response)
{
var data = response.data;
console.log("Success: "+JSON.stringify(data));
},
function(response)
{
var data = response.data || "Request failed";
var status = response.status;
console.error("Error: "+JSON.stringify(data));
}
);
}
IE Browsers will catch ajax get requests even if we add cache control headers to the response. Only way i found to solve the issue is to add some random parameter to the request. Please make sure the api have no problem even if you send extra parameters
MyService.HttpReq("testUrl?ts=" + Date.now(), "GET", null);
Just add cache: false attribute to config object.
https://docs.angularjs.org/api/ng/service/$http#caching
Also you can add header: 'Cache-Control' : 'no-cache'

Resources