In my angular app, I want to use angular custom header. I'm using the following code::
Angular Factory
angular.module('app').factory('UserAPI', ['$resource', 'session', function($resource, session) {
var mainUrl = 'http://localhost:8006/dev' + '/users';
return {
getService : function() {
var token = session.getToken();
console.log(token); //token is printed here
return $resource(mainUrl, { }, {
getData: {
method: 'GET',
url: mainUrl + '/:userId/dashboard',
isArray: true,
headers: { 'Token': token }
}
});
}
}
}]);
Angular Controller
angular.module('app').controller('UserCtrl', ['$scope', 'UserAPI', function($scope, UserAPI) {
var user = UserAPI.getService();
user.getData({ userId: 'some-user-id' }, {}, function(res) {
}, function(err) {
});
}]);
When I make call user.getUser(......), an url is generated as like as GET:: http://localhost:8006/dev/user/some-user-id/dashboard instead of GET:: http://localhost:8006/dev/user/some-user-id/dashboard?token=SomeVeryLongToken, I mean token is missing on api call, although I'm using headers: { 'Token': token } but still problem.
How can I solve this problem?
NB "angular": "^1.4.0",
"angular-resource": "^1.4.0",
change headers: { 'Token': token } to params: { 'token': token }
You're adding token as a request header, not as a property in the query string. Use the second (in your example empty) object to add parameters, or add them directly in your controller:
user.getUser({token: 'sometoken'}, {}, function(res) {
}, function(err) {
});
Related
My service code:
application.factory('Http', function($http) {
var base_url = "Angular_Database/server.php";
return {
post: function(form_data) {
var request = $http({
method: 'POST',
url: base_url,
data: form_data
});
return request;
},
send: function(request, callback) {
request.then(function(response) {
callback(response);
}).error(function(Object) {
alert(Object.data);
});
}
}
})
here, The problem is in the .then().
My console says:
Type:Error request.then(...) error is not a function
There is no error() function in the HttpPromise object starting from Angular 1.5.X (Based on comment). You need to use catch() function instead of it.
request.then(function(response) {
callback(response);
}).catch(function(Object) {
alert(Object.data);
});
Also could be:
request.then(function(response) {
callback(response);
}, function(error){
alert(error.data);
})
I'm calling a method inside my Web Api 2 controller, passing in a model called login which consists of EmailAddress and Password. However it hits the method but the model passed in is always null...
My call from AngularJs function :
var login = { "EmailAddress": emailAddress, "Password": password };
$http.post("/api/Login/", { headers: { 'RequestVerificationToken': $scope.antiForgeryToken } }, login).success(function () {
alert('succes');
}).error(function () {
alert('Unable to login at present, please try again later');
});
My method:
[ValidateAntiForgeryToken]
public void Post([FromBody]Login login)
{
var t = login.EmailAddress;
}
I think its something to do with how I've structure my actual Angular $http.post method but again I'm not sure, can anyone suggest would could potentially be wrong with it?
Can you use ajax and Razor?
var login = { "EmailAddress": emailAddress, "Password": password };
$.ajax({
url: "#Url.Action("api/login", "Controller", login)",
type: "GET",
data: {},
success: fCheckBoxes
});
Why cannot add the token to every request by configuring your app.js
// Set header for every request
app.factory('httpRequestInterceptor', function ($localStorage) {
return {
request: function (config) {
if ($localStorage.token != null)
config.headers['myAppToken'] = $localStorage.token;
return config;
}
};
});
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
});
I have multiple factories in my angular service located in different js file. And there is common base of all the queries:
1) Authorization: Bearer token (header) (required after login)
2) AccessDateTime, UserIPAddress (required before login)
3) AccessDateTime, UserIPAddress, UserID (required after login)
Now, I find that it is very tedious to repeat this on each of the resource. How could i make a base for this? I thought that this is something very common but i could not found any documentation on this. Something like jquery.AjaxSetup().
Default Code
angular.module('app.test').factory('Test', ['$resource',
function($resource) {
return {
resource1: $resource(
url: 'test1/:testId/:AccessDateTime/:UserIPAddress',
headers: { Authorization: Bearer token},
params: { testId: '#_id', AccessDateTime:'#AccessDateTime', UserIPAddress: '#UserIPAddress' }
}),
resource2: return $resource(
url: 'test2/:testId/:AccessDateTime',
params: { testId: '#_id', AccessDateTime:'#AccessDateTime' }
});
}
}
]);
Code after base resource implemented(Illustration only)
angular.module('app.base').factory('FactoryBase'), ['resource',
function($resource) {}
if (resource need authorization) {
auto append header, AccessDateTime, UserIPAddress
} else if (resource do not need authorization) {
auto append AccessDateTime
}
// depending on attribute set with authorize: true/false
}
]);
angular.module('app.test').factory('Test', ['$resource',
function($resource) {
require('FactoryBase'),
return {
resource1: $resource(
url: 'test1/:testId',
authorize: true
}),
resource2: $resource(
url: 'test2/:testId',
authorize: false
}),
}
]);
Put modifier functions in your factory:
angular.module('app.test').factory('Test', ['$resource',
function($resource) {
var defaultConfig1 = {
url: 'test1/:testId/:AccessDateTime/:UserIPAddress',
headers: { Authorization: Bearer token},
params: { testId: '#_id',
AccessDateTime:'#AccessDateTime',
UserIPAddress: '#UserIPAddress'
}
};
var defaultConfig2 = {
url: 'test2/:testId/:AccessDateTime',
params: { testId: '#_id',
AccessDateTime:'#AccessDateTime'
}
};
function mod1(arg) {
var obj = defaultConfig1;
//modify config
return obj;
};
function mod2(arg) {
//modify and return defaultConfig
};
return {
resource1: $resource(defaultConfig1),
resource2: $resource(defaultConfig2).
modified1: function (arg) {
return $resource(mod1(arg));
},
modified2: function (arg) {
return $resource(mod2(arg));
}
}
}
]);
You have the full power of JavaScript to modify the configuration objects as you please before returning them.
$http.post('http://localhost:7001/v1/sessions', {
data: {
username: $scope.user.username,
password: $scope.user.password,
type: 'sessions'
}
})
.then(function(response) {
if(response.data.data.token) {
$http.defaults.headers.common.Authorization = response.data.data.token;
$state.go('app.dashboard');
} else {
$scope.authError = response;
}
}, function(x) {
$scope.authError = 'Server Error';
});
I can confirm that the if condition gets called and a response.data.data.token is present.
It goes to the app.dashboard state but is intercepted by my ui-router:
$stateProvider.state('app', {
abstract: true,
url: '/app',
templateUrl: 'tpl/app.html',
resolve: {
current_user: ['$http', function($http) {
return $http.get('http://localhost:7001/v1/users/4/entities');
}]
}
})
That call, however, does not have anything set in the header. I thought that $http.defaults would set a default value in the header. What am I doing incorrectly?
You must set the default headers in the config method and not in your service.
Example:
myApp.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.common['Content-Type'] = 'application/json; charset=utf-8';
}]);
Only in config you can configure the httpProvider. If you try to do that inside your service, it won't affect the $httpProvider service at all.
EDIT:
You must make use Interceptors in this scenario.
For purposes of global error handling, authentication, or any kind of
synchronous or asynchronous pre-processing of request or
postprocessing of responses, it is desirable to be able to intercept
requests before they are handed to the server and responses before
they are handed over to the application code that initiated these
requests.
Refer Angular Docs Interceptor section
Just some sample code:
app.service('APIInterceptor', function($rootScope, UserService) {
var service = this;
service.request = function(config) {
// check if the token is available. Once the token is available get it here from the UserService.
var access_token = UserService.getToken() || "unauthorized";
if (access_token) {
config.headers.authorization = access_token;
}
return config;
};
service.responseError = function(response) {
return response;
};
})
In your config
$httpProvider.interceptors.push('APIInterceptor');
I would prefered you to one service to use sharable data.
Code
app.service(dataService, function(){
this.data = {}
this.getData = function(){
return data;
};
this.setTokenData = function(token){
data.token = token;
}
});
Now your code would be while setting token you could use dataService
if(response.data.data.token) {
dataService.setTokenData(response.data.data.token);
$http.defaults.headers.common.Authorization = dataService.data.token; //dataService.getData().token;
$state.go('app.dashboard');
} else {
$scope.authError = response;
}
Then from service resolve you could use
$stateProvider.state('app', {
abstract: true,
url: '/app',
templateUrl: 'tpl/app.html',
resolve: {
current_user: ['$http', 'dataService', function($http, dataService) {
$http.defaults.headers.common.Authorization = dataService.getData().token;
return $http.get('http://localhost:7001/v1/users/4/entities');
}]
}
})
lb.services:-
"login": {
url: urlBase + "/Vendors/login",
method: "POST"
},
only this return type i`m able to get.
but it should be like dis:-
"login": {
params: {
include: "user"
},
interceptor: {
response: function(response) {
var accessToken = response.data;
LoopBackAuth.setUser(accessToken.id, accessToken.userId, accessToken.user);
LoopBackAuth.rememberMe = response.config.params.rememberMe !== false;
LoopBackAuth.save();
return response.resource;
}
},
url: urlBase + "/Users/login",
method: "POST"
},
See my example on Angular with LoopBack here: https://github.com/strongloop/loopback-example-angular