Add data to POST on every $http request with AngularJS - javascript

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;
}
};
});

Related

http post response is null

I'm sending http post request to REST api, I'm getting status ok response from server but in this script, it always runs 'myError' function. In backend everything is running fine without any error. In error function also response value remains undefined.
var toDoApp = angular.module('toDoApp');
toDoApp.factory('registrationService', function() {
var register = {};
register.registeruser = function(user, $http) {
$http({
method : "POST",
url : 'register',
data : user
}).then(function mySuccess(response) {
console.log("success");
}, function myError(response) {
console.log("error");
});
}
return register;
});
Inject the http service to the factory. Not the registeruser function.
toDoApp.factory('registrationService', function($http) {
Do some needful correction.
var toDoApp = angular.module('toDoApp',[]);
toDoApp.factory('registrationService', function($http) {
var register = {};
register.registeruser = function(user) {
$http({
method : "POST",
url : 'register',
data : user
}).then(function mySuccess(response) {
console.log("success");
}, function myError(response) {
console.log("error");
});
}
return register;
});
Error is showing because you did not inject $http service to to your toDoAppfactory not in your registeruser function . You should inject $http service to your factory. like :
toDoApp.factory('registrationService', function($http)
And your function registeruser should be like
register.registeruser = function(user) {
$http({
method : "POST",
url : 'register',
data : user
}).then(function mySuccess(response) {
console.log("success");
}, function myError(response) {
console.log("error");
});
}

Consume AngularJS service from simple javascript

I have a main.js javascript file that has an init() function in.
I also have this AngularJS service:
(function () {
var app = angular.module('spContact', ['ngRoute']);
app.factory('spAuthService', function ($http, $q) {
var authenticate = function (userId, password, url) {
var signInurl = 'https://' + url + '/_forms/default.aspx?wa=wsignin1.0';
var deferred = $q.defer();
var message = getSAMLRequest(userId, password, signInurl);
$http({
method: 'POST',
url: 'https://login.microsoftonline.com/extSTS.srf',
data: message,
headers: {
'Content-Type': "text/xml; charset=\"utf-8\""
}
}).success(function (data) {
getBearerToken(data, signInurl).then(function (data) {
deferred.resolve(data);
}, function (data) {
deferred.reject(data)
})
});
return deferred.promise;
};
return {
authenticate: authenticate
};
function getSAMLRequest(userID, password, url) {
return 'envelope';
}
function getBearerToken(result, url) {
var deferred = $q.defer();
var securityToken = $($.parseXML(result)).find("BinarySecurityToken").text();
if (securityToken.length == 0) {
deferred.reject();
}
else {
$http({
method: 'POST',
url: url,
data: securityToken,
headers: {
Accept: "application/json;odata=verbose"
}
}).success(function (data) {
deferred.resolve(data);
}).error(function () {
deferred.reject();
});
}
return deferred.promise;
}
});
})();
How can I call this services "authenticate" method from the init() function of my main JavaScript file?
This service should return some authentication cookies that I would need for data querying.
You need to inject this factory to some controller/directive like:
app.controller('MyCtrl', ['spAuthService', function (spAuthService) {
spAuthService.authenticate.then(function (data) {
// ...
});
}]);
And this controller MyCtrl may be put on some home page and bootstrapped by Angular automatically.

Angular Service - Return http response

I'm trying to build an angular service I can reuse for doing my http requests etc. This all works when it's not in a service.
The following code works and does the login, but the log of $scope.data is always undefined. If i put a log in on the success before I return data it returns the data, but not back to the controller which is what i'm really looking to do.
Just for clarification, I want to be able to access the json data returned from the server as 'data' in the success in my controller.
//App.js
.service('SaveSubmitService', function ($http, $log) {
this.addItem = function(url, options){
var xsrf = $.param({
Username: options.Username,
Password: options.Password
});
$http({
method: 'POST',
url: url,
data: xsrf,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function(data, status, headers, config) {
return data;
}).
error(function(data, status, headers, config) {
console.log(data);
return false;
});
}
})
Controller:
.controller('LoginCtrl', function ($scope, $stateParams, $location, $ionicLoading, $http, SaveSubmitService, $log) {
if (localStorage.getItem("SessionKey")) {
$location.path('home');
}
$scope.login = {};
$scope.doLogin = function doLogin() {
$scope.data = SaveSubmitService.addItem('http://*****/Services/Account.asmx/Login', $scope.login);
$log.info($scope.data);
};
})
First of all make SaveSubmitService return promise object. Then use its API to provide a callback to be executed once data is loaded:
.service('SaveSubmitService', function ($http, $log) {
this.addItem = function (url, options) {
var xsrf = $.param({
Username: options.Username,
Password: options.Password
});
return $http({
method: 'POST',
url: url,
data: xsrf,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function(response) {
return response.data;
})
.catch(function(error) {
$log.error('ERROR:', error);
throw error;
});
}
});
And the you will use it like this in controller:
$scope.doLogin = function doLogin() {
SaveSubmitService.addItem('http://*****/Services/Account.asmx/Login', $scope.login).then(function(data) {
$scope.data = data;
$log.info($scope.data);
});
};
Note, how you return result of $http function call, it returns Promise which you use in controller.
saveSubmitService Service method is returning promise and it can be resolved using .then(function())
Your controller code will look like below.
CODE
$scope.doLogin = function doLogin() {
var promise = saveSubmitService.addItem('http://*****/Services/Account.asmx/Login', $scope.login);
promise.then(function(data) {
$scope.data = data
});
};
Thanks
.factory('SaveSubmitService', function ($http, $log) {
return{
getData:function(url,xsrf)
{
$http({
method: 'POST',
url: url,
data: xsrf,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function(data, status, headers, config) {
return data;
}).
error(function(data, status, headers, config) {
console.log(data);
return false;
});
}
}
})
.controller('LoginCtrl', function ($scope, $stateParams, $location, $ionicLoading, $http, SaveSubmitService, $log) {
if (localStorage.getItem("SessionKey")) {
$location.path('home');
}
$scope.login = {};
$scope.doLogin = function doLogin() {
$scope.data = SaveSubmitService.addItem(, );
$log.info($scope.data);
};
SaveSubmitService.getData('http://*****/Services/Account.asmx/Login',$scope.login).success(function(data,status){
$scope.data
}).error(function(data,status){ });
)};

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) {
//...
});
}

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

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"
};

Categories