Angular not getting response when it's a non-200 - javascript

I've impelmented the httpInterceptor found here.
If my Basic Auth header has valid credentials, everything works fine, but if I get back a 401, then the application just hangs and I never receive a response.
Here's my interceptor:
angular.module('TDE').factory('httpInterceptor', function httpInterceptor ($q, $window, $location) {
return function (promise) {
var success = function (response) {
//window.logger.logIt("httpInterceptor received a good response: " + response);
return response;
};
var error = function (response) {
//window.logger.logIt("httpInterceptor received an error: " + response);
if (response.status === 401) {
$location.url('/login');
}
return $q.reject(response);
};
return promise.then(success, error);
};
});
Declaring the httpInterceptor in app.js
angular.module('TDE', []);
var TDE = angular.module('TDE', ['ux', 'ngRoute', 'ngResource', 'TDE', 'hmTouchEvents', 'infinite-scroll', 'ui.bootstrap', 'ui.sortable']);
TDE.config(['$routeProvider', '$locationProvider', '$httpProvider', function ($routeProvider, $locationProvider, $httpProvider) {
$httpProvider.responseInterceptors.push('httpInterceptor');
$routeProvider
.when('/', {})
.when('/login', { templateUrl: "Views/Login/login.html", controller: "LoginController" })
And my authenticate method
authenticate: function (user, password) {
// window.logger.logIt("serviceAccount: " + $rootScope.serviceAccount);
window.logger.logIt("In authenticate...");
var deferred = $q.defer();
var encoded = encoder.encode($rootScope.serviceAccount);
//var encoded = encoder.encode(user + ":" + password);
if (user && password) {
window.logger.logIt("We've got a username and password...");
$http.defaults.headers.common.Authorization = 'Basic ' + encoded;
sessionStorage.setItem('Authorization', $http.defaults.headers.common.Authorization);
var url = $rootScope.serviceBaseUrl + "login/authenticate";
window.logger.logIt(url);
$http({
method: "POST",
url: url,
data: {
"Username": user,
"Password": password,
"AccessToken": ""
},
headers: {
"Content-Type": "application/json"
}
})
.success(function (data, status, headers, config) {
window.logger.logIt("We've got a response (success)...");
if (data.IsAuthenticated) {
deferred.resolve(data);
session.setSession();
} else {
deferred.reject(status);
}
})
.error(function (data, status, headers, config) {
window.logger.logIt("We've got a response (error)...");
$dialogservice.showMessage("Authentication Error", "Return Code: " + status);
deferred.reject(status);
});
} else {
window.logger.logIt("We've got a response...");
deferred.reject(401);
}
return deferred.promise;
},
You'll see that in my Authenticate method, there are two lines that I'm testing:
var encoded = encoder.encode($rootScope.serviceAccount);
and
var encoded = encoder.encode(user + ":" + password);
We are REQUIRED to use Basic Authentication (which is over SSL). Right now, all I'm testing is that I can receive a 401 back. If I use the $rootScope.serviceAccount (which is working), I get a 200 response right away. But if I purposely send a bad username/password, I NEVER get a response, the application just sits there.
Edit: Ok, I've updated my code to the following, and still getting the same behavior:
angular
.module('TDE')
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.interceptors.push(function ($q) {
return {
'request': function (config) {
window.logger.logIt("Request is being sent...");
var headers = config.headers;
if (!headers.Authorization) {
headers.Authorization = sessionStorage.getItem('Authorization');
}
return config || $q.when(config);
},
'response': function (response) {
window.logger.logIt("got a good response...");
return response;
},
'responseError': function (rejection) {
window.logger.logIt("responseError error...");
return $q.reject(rejection);
},
};
});
}]);

Well, again, PhoneGap is the issue!!!!!!!!!!!!!!!!!
Example 1
Example 2
Example 3
Example 4

Try this interceptor:
.factory('httpInterceptor', function(){
return {
request : function(yourRequestConfig){
var returnPromise = $q.defer();
$http(yourRequestConfig).then(function(response) {
console.log("successful response from server ", response);
returnPromise.resolve(response);
}, function(someReason) {
console.log("failure response from server", reason);
returnPromise.reject(reason);
});
return returnPromise.promise;
}
}
});
used as
httpInterceptor.request(request config).then(returnValue){
console.log('inside controller', returnValue);
});
where request config is something like:
var requestConfig = {
method: "GET",
url: "localhost:8080/getStuff"
};

Related

Redirecting to another page prevents functions from returning their values

I have a Login page and if user logs in I want to redirect the user to another HTML page where I will list users tasks that I get from server.
The problem is:
Even though the functions I wrote works properly and backend API returns the values I want (I can see the value details on Console) when I use redirect code $window.location.href = '../Kullanici/userPanel.html the page redirects immedietly after login and for some reason I can't use the values returned by functions after redirection. Not only that I can't see the details of the value returned on console log anymore.
And here is my code for it:
Controller:
app.controller('myCtrl', ['$scope', '$http', '$window','$mdToast', 'userTaskList',
function ($scope, $http, $window, $mdToast, userTaskList) {
$scope.siteLogin = function () {
var userName = $scope.panel.loginUserName;
var password = $scope.panel.loginPassword;
var loginMember = { //JSON data from login form
K_ADI: $scope.panel.loginUserName,
PAROLA: $scope.panel.loginPassword
};
$http({
method: 'POST',
url: 'http://localhost:5169/api/Kullanicilar/KullaniciDogrula',
headers: {
'Content-Type': 'application/json'
},
data: loginMember
}).then(function successCallback(response) {
console.log("message sent", response);
$scope.data = response.data.error.data;
if ($scope.data === true) {//if username and password is correct
console.log("User exists");
userTaskList.showActiveTasks(userName)
.then(function (activeTaskResponse) {
var activeTasks = activeTaskResponse;
console.log("Active tasks (controller): ", activeTaskResponse);
userTaskList.showFinishedTasks(userName)
.then(function (finishedTaskResponse) {
var finishedTasks = finishedTaskResponse;
console.log("Finished tasks(controller): ", finishedTaskResponse);
$scope.getMessage();
$window.location.href = '../Kullanici/userPanel.html';
}, function (err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
}
}, function errorCallback(response) {
console.log("Couldn't send", response);
});
}
So what causes this problem and how can I fix it?
Edit: I nested .then parts but it doesnt work properly and gives This value was just evaluated now warning. So I stil can't use data on the redirected HTML page.
I also removed the factory since it makes the code look really messy and its probably not the source of the problem.
I would have nested the your two functions inside the first promise, then redirect once all of them are done. Something like
app.controller('myCtrl', ['$scope', '$http', '$window','$mdToast', 'userTaskList',
function ($scope, $http, $window, $mdToast, userTaskList) {
$scope.siteLogin = function () {
var userName = $scope.panel.loginUserName;
var password = $scope.panel.loginPassword;
var loginMember = { //JSON data from login form
K_ADI: $scope.panel.loginUserName,
PAROLA: $scope.panel.loginPassword
};
$http({
method: 'POST',
url: 'http://localhost:5169/api/Kullanicilar/KullaniciDogrula',
headers: {
'Content-Type': 'application/json'
},
data: loginMember
}).then(function successCallback(response) {
console.log("message sent", response);
$scope.data = response.data.error.data;
if ($scope.data === true) {//if username and password is correct
console.log("User exists");
userTaskList.showActiveTasks(userName)
.then(function (res) {
var activeTasks = res;
console.log("Active tasks (controller): ", res);
userTaskList.showFinishedTasks(userName)
.then(function (res) {
var finishedTasks = res;
console.log("Finished tasks(controller): ", res);
$scope.getMessage();
$window.location.href = '../Kullanici/userPanel.html';
}, function (err) {
console.log(err);
});
}, function (err) {
console.log(err);
});
} else { //if username or password is wrong
$mdToast.show(
$mdToast.simple()
.textContent('Username or Password is wrong')
.position('right')
.hideDelay(3000)
);
}
}, function errorCallback(response) {
console.log("Couldn't send", response);
});
}
}
]);
Oh I injected ngRoute to my AngularJS module but haven't use it yet.
Using $window.location.href kills the app and loads the other page, losing $rootScope, $scope, and all service data.
Re-factor your code to use a router and store the data in a service:
$routeProvider
.when('/userPanel' , {
templateUrl: 'partials/userPanel.html',
controller: panelController
})
panelService.set(data);
$location.path("/userPanel.html");
OR use localStorage to store the data:
localStorage.setItem('panelData', JSON.stringify(data));
$window.location.href = '../Kullanici/userPanel.html';
Data stored in a service will survive route changes (which destroy $scope). Data stored in localStorage will survive page changes (which destroy apps).
The code can be simplified
This will solve the problem of having the page wait for the data before changing the route.
Since the getMessages function makes an HTTP request it needs to be modified to return a promise:
$scope.getMessages = getMessages;
function getMessages() {
return $http({
method: 'GET',
url: 'http://localhost:5169/api/chat/chatCek'
}).then(function successCallback(res) {
console.log("Mesajlar", res);
$scope.messages = res.data.error.data;
return res.data.error.data;
}, function errorCallback(res) {
console.log("Hata", res);
throw res;
});
}
Then to delay the changing of the route until the getMessages data returns from the server, chain from the getMessages promise:
$http({
method: 'POST',
url: 'http://localhost:5169/api/Kullanicilar/KullaniciDogrula',
data: loginMember
}).
then(function successCallback(response) {
console.log("message sent", response);
$scope.data = response.data.error.data;
if ($scope.data !== true) { throw "user error" };
//username and password is correct
console.log("User exists");
return userTaskList.showActiveTasks(userName);
}).
then(function (activeTaskResponse) {
var activeTasks = activeTaskResponse;
console.log("Active tasks (controller): ", activeTaskResponse);
return userTaskList.showFinishedTasks(userName)
}).
then(function (finishedTaskResponse) {
var finishedTasks = finishedTaskResponse;
console.log("Finished tasks(controller): ", finishedTaskResponse);
//CHAIN from getMessages promise
return $scope.getMessages();
}).
then(function(data) {
console.log(data);
//SAVE data before changing route
panelService.set(data);
$location.path( "/userPanel" );
//OR STORE data before changing app
//localStorage.setItem('panelData', JSON.stringify(data));
//$window.location.href = '../Kullanici/userPanel.html';
}).
catch(function (response) {
console.log("Couldn't send", response);
throw response;
});

Add data to POST on every $http request with AngularJS

I want to send custom POST parameter (CSRF token) on every $http post request on AngularJS. I tried with an interceptor, it works but is sending parameter as GET, and I need to send as POST.
Basically I need something like $.ajaxSetup() on jQuery.
$http request:
App.controller('LoginController', function ($scope, $window, $http)
{
$scope.email = undefined;
$scope.password = undefined;
$scope.login = function() {
var request = $http({
method: "POST",
url: gurl + 'user/login',
// headers: {'Content-Type' : 'application/x-www-form-urlencoded', 'X-Requested-With' :'XMLHttpRequest'},
data: $.param({email: $scope.email, password: $scope.password})
});
request.success(function(data) {
if(angular.equals(data.status, 'success')) {
$window.location.href = gurl + 'dashboard';
}
else {
noty('error', data.msg);
}
});
}
});
Interceptor
App.factory('csrfInterceptor', function($q, $location, $injector)
{
return {
// optional method
'request': function(config) {
// do something on success
config.param = config.param || {};
config.param.csrf_token = $("input:hidden[name='csrf_token']").val();
return config;
}
};
});

Angular $http set cookie on each request after login

I'm having troubles with $http calls in AngularJS. I've created the following services
crApp.service('authService', function ($http) {
var urlBase = 'http://192.168.xx.xx:8081';
// POST api/login/
this.login = function (credentials) {
return $http.post(urlBase + "/api/login", credentials);
};
// POST api/logout/
this.logout = function () {
return $http.post(urlBase + "/api/logout/", "");
};
}); //end service
crApp.service('dataService', function ($http) {
var urlBase = 'http://192.168.xx.xx:8081';
// POST api/query/
this.pull = function (query) {
return $http.post(urlBase + "/api/query", query);
};
From the controller I call the login method:
$scope.login = function(){
authService.login(credentials)
.success(function(data) {
console.log("RESULT LOGIN: " + data );
})
.error(function(data, status, headers, config) {
console.log(data);
console.log(status);
console.log(headers);
console.log(config);
});
};
So far so good and I receive a response where a cookie is set:
After succesfull login I call the following method:
var locations = { query: "from location select uid, name, description, address, phone", dataFormat: "verbose" };
$scope.getLocations = function() {
dataService.pull(portals)
.success(function (data) {
console.log("RESULT QUERY: " + data)
})
.error(function(data, status, headers, config) {
console.log("Query niet gelukt!");
console.log(data);
console.log(status);
console.log(headers);
console.log(config);
});
};
Result:
So cookie is not set in the headers.
I'm using AngularJS 1.3.15 and calls are made to a remote server on a different domain, but it does work in the REST Client tool in WebStorm (Jetbrains). So it must be something i'm missing in Angular!??
Hopefully someone can help me out.
You need to set withCredentials = true in the $http config to allow cookies to be set on CORS requests. This article explains more about cookies and CORS.
In your app config:
$httpProvider.defaults.withCredentials = true;
For example:
angular.module('myApp', [])
.config(['$httpProvider'){
$httpProvider.defaults.withCredentials = true;
}]);
You can read about this option in the $http provider documentation.

How to rewrite headers in $httpProvider config.headers with new $http request

In AngularJS I have config for default headers (for Authentification)
it works fine, every $http request going with right headers.
But for some request I need to change this headers to another values. But I cant! I can only add new one, but can't rewrite previous value.
Thanks!
Here is a thousands lines of code, so there is most important part of this issue
//THIS PART OF CONFIG
.config(['$locationProvider',
'$stateProvider',
'$urlRouterProvider',
'$httpProvider',
function ($locationProvider, $stateProvider, $urlRouterProvider, $httpProvider){
//....
$httpProvider.interceptors.push('AuthInterceptor');
}
// THIS FACTORY
.factory('AuthInterceptor', ['$q',
function($q) {
return {
request: function(config) {
config.headers = config.headers || {};
config.headers.Authorization = 'OldValue';
return config || $q.when(config);
},
response: function(response){
if (response.status === 401) {
console.log('Response 401');
}
return response || $q.when(response);
},
responseError: function(rejection) {
if (rejection.status === 401) {
console.log('Response Error 401',rejection);
}
return $q.reject(rejection);
}
};
}
])
//THIS PART OF CONTROLLER
$scope.makeRequest = function(){
var request = $http({
method: 'GET',
headers: {
'Authorization' : 'NewValue', // do not work
'NewAuthorisatnion' : 'AnotherValue' // works fine
url: '/'
});
request.
success(function (data) {
//...
});
}

Internal Server error on post Request Using Made Custom Services in Angular js

i am new one for angular so i tried my best to solve this but after too much struggle i can't that's why asking. actually, i am not getting response back using $http i don't why because according to me it's seems right.
Two Questions For This Problem
1- Post Request Fail
2- How CookieStore In angular
signUpController.js
app.controller('signUpController', function ($rootScope, $scope, signUpService, $location) {
$scope.addUser = function(){
var user = {
"email": $scope.EmailInfo,
"confirm_email": $scope.ConfirmEmailInfo,
"password": $scope.PasswordInfo,
"confirm_password": $scope.ConfirmPasswordInfo,
"first_name": $scope.FirstnameInfo,
"last_name": $scope.LastNameInfo,
"dob": $scope.dateOfBirth,
"gender": $scope.radioValue
}
signUpService.addNewUser(user).then(function(response) {
if(response.status == 500) {
$rootScope.loggedIn = false;
$location.url('/SignUp');
}else {
$rootScope.loggedIn = true;
$location.url('/Stores');
console.log(data);
}
console.log(response);
});
}
});
signUpService.js
app.factory('signUpService', function($http, $cookieStore) {
var signUpServices = {
addNewUser : function(user) {
var promise = $http({
method:'POST',
url: "/user/register?account_id=" + utils.urlParam('account_id') ,
data: user
}).then(function(response) {
$cookieStore.put("token", response["token"]); // is it write that i used also check please
console.log(response.data);
return response.data;
},
function(reason) {
alert("There was a problem");
});
return promise;
}
};
return signUpServices;
});
error
POST http://localhost:3000/user/register?account_id=0 500 (Internal Server Error) angular.js:10159
(anonymous function) angular.js:10159
sendReq angular.js:9980
$http.serverRequest angular.js:9757
deferred.promise.then.wrappedCallback angular.js:7303
deferred.promise.then.wrappedCallback angular.js:7303
(anonymous function) angular.js:7340
Scope.$eval angular.js:8685
Scope.$digest angular.js:8548
Scope.$apply angular.js:8771
(anonymous function) angular.js:13970
f.event.dispatch jquery.js:3
h.handle.i
Updated But Same Issue
app.factory('signUpService', function($http) {
var signUpServices = {
addNewUser : function(user) {
var promise = $http({method: 'POST', url: "/user/register?account_id=" + utils.urlParam('account_id'),
data: user}).
success(function(data, status, headers, config) {
console.log("response");
alert(data);
}).
error(function(data, status, headers, config) {
alert(status);
});
return promise;
}
};
return signUpServices;
});
i will be really grateful to you if someone rectify this where need to required changes.
You are using $http wrong
$http({method: 'GET', url: '/someUrl'}).
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Here is how you can get cookie on each request:
$http.defaults.transformRequest.push(function (data) {
data.csrfToken = $browser.cookies().csrfToken;
return angular.toJson(data);
});

Categories