Response of a service is null in another service in Angujar JS - javascript

I'm trying to create a service from a $resource, because the request needs authentication, I'm sending an Authorization header.
So I have 2 services:
authService
userInforService
authService:
var ouveerApiServices = angular.module('ouveerServices.api', []);
ouveerApiServices.factory('authService', ['$http', '$rootScope', 'localStorageService', 'apiService',
function($http, $rootScope, localStorageService, apiService){
return {
isLogged : function(){
return (localStorageService.get('accessToken')) ? true : false;
},
logIn : function(email, password){
var dataQuery = $.param({
grant_type: "password",
username : email,
password : password
});
return $http({
url: $rootScope.apiURL + 'Auth',
method: 'POST',
data : dataQuery,
withcredentials : true,
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
}
});
},
logOut : function(){
return apiService.post({ url: 'api/Account/Logout' });
},
getAccessToken : function(){
return localStorageService.get('accessToken');
}
} //return
} //function
]);
And the userInfoService:
var ouveerUserServices = angular.module('ouveerServices.user', []);
//user related queries
ouveerApiServices.factory('userInfoService', ['$resource', '$rootScope', 'localStorageService', 'authService',
function($resource, $rootScope, localStorageService, authService){
return $resource($rootScope.apiURL + 'api/users/:userId', { userId : '#id' }, {
update : {
method: 'PUT',
isArray : false
},
account : {
method : 'GET',
isArray : false,
url: $rootScope.apiURL + 'api/Account/UserInfo',
headers : {
'Authorization' : 'Bearer ' + authService.getAccessToken()
}
}
});
}
]);
The problems is at the time I call (in a controller):
$scope.signIn = function(){
$scope.messages = [];
console.log($scope.user.semail);
if($scope.user.semail && $scope.user.spassword){
authService.logIn($scope.user.semail, $scope.user.spassword).success(function(data){
localStorageService.add('accessToken', data.access_token);
console.log(authService.getAccessToken());
//setting userID in localstorage
userInfoService.account(function(){
localStorageService.add('userId', userData.userId);
$location.path('/library');
});
}).error(function(){
$scope.status = 'error';
$scope.messages[0] = ['Review the fields please, something is wrong...'];
});
} else {
$scope.status = 'error';
$scope.messages[0] = ['Type your email and password.'];
}
}
It returns null, but as you note I'm dumping the var just before the call of userInfoService and it response the Auth code, anything I'm doing wrong?

Note that you initialize the account property in following way:
account : {
method : 'GET',
isArray : false,
url: $rootScope.apiURL + 'api/Account/UserInfo',
headers : {
'Authorization' : 'Bearer ' + authService.getAccessToken()
}
}
This code (including authService.getAccessToken()) is run upon the creation of the service, i.e long before the code in the controller. Hence, authService.getAccessToken() is resolved, and at that point in time it is null.
To put another way, when you try to actually use the header in the account resource, it is just a string, created long ago.

Related

The right way to call http for every route AngularJs

I really new with AngularJs and I'm trying to create multiple routes with different $http requests. My problem start when the route change and the page content show later.
I figure it out in some way and i think its not the right way.
Hope someone can tell me if there is a better way.
Note: AngularJs version: 1.6 | Using ui router
main.js
var asTwl = angular.module('asTwl', ['ui.router']);
asTwl.controller('generals', function($scope, $http, $timeout){
$scope.pageLoader = false;
$scope.getPageData = function(path, postData, obj){
$scope.pageLoader = true;
$http({
method: 'post',
url: path,
data: postData,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(function(response) {
if (response.data) {
$scope.data[obj] = JSON.parse(response.data);
$timeout(function(){
$scope.pageLoader = false;
}, 100)
}
})
.catch(function(e) {
new Error('Error: ', e);
throw e;
})
}
});
asTwl.controller('homePage', function($scope, $http){
var postData = {
//data...
}
$scope.getPageData('path', postData, 'home')
})
asTwl.controller('singlePage', function($scope, $http, $stateParams){
var postData = $stateParams;
$scope.getPageData('path', postData, 'page')
})
asTwl.controller('categoryPage', function($scope, $http, $stateParams){
var postData = $stateParams;
$scope.getPageData('path', postData, 'category')
})
asTwl.config(function($stateProvider, $urlRouterProvider, $locationProvider){
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl : 'templates/pages/home.html',
controller : 'homePage'
})
.state('info', {
url: '/info/:id',
templateUrl : 'templates/pages/info.html',
controller : 'singlePage'
})
.state('category', {
url: '/category/:type/:id',
templateUrl : 'templates/pages/category.html',
controller : 'categoryPage'
})
});
Thank you!
First, wrap your $http calls to services. Next,try to use resolve https://github.com/angular-ui/ui-router/wiki#resolve
Edit
Ok, example is here (without wrapping to service):
$stateProvider
.state('home', {
url: '/',
templateUrl : 'templates/pages/home.html',
controller : 'homePage',
resolve: {
routeData: function($http){
return $http({
method: 'post',
url: 'path',
data: postData /* your POST data - i don't know what is it for your code*/,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
})
}
}
})
.state('info', {
url: '/info/:id',
templateUrl : 'templates/pages/info.html',
controller : 'singlePage'
})
.state('category', {
url: '/category/:type/:id',
templateUrl : 'templates/pages/category.html',
controller : 'categoryPage'
})
And in controller:
asTwl.controller('homePage', function($scope, routeData){
$scope.someData = routeData;
})
You should first create a service which will be responsible for communicating with Server/API for playing around with data. You could include that method getPageData in that, it returns a promise object.
Service
app.service('myService', function($http){
var self = this;
self.getPageData = function(path, postData){
return $http.post(path,postData, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' });
.catch(function(e) {
new Error('Error: ', e);
throw e;
});
});
Then you could easily utilize the resolve option of state of ui-router will wait till your ajax promise gets resolved.
.state('info', {
url: '/info/:id',
templateUrl : 'templates/pages/info.html',
controller : 'singlePage',
resolve: {
getData: function(myService) {
return myService.getPageData('path', {}, 'info')
}
}
})
In a nutshell your routes have to be changed like this:
.state('category', {
resolve: {
data : ($stateParams, dataService) => dataService.getData('path', $stateParams, 'category')
},
url: '/category/:type/:id',
templateUrl : 'templates/pages/category.html',
controller : 'categoryPage'
})
And getData method should be refactored to the service (dataService)

AngularJS nullable parameter missing in ASP.NET Web Service method

I am calling an ASP.NET Web Service Method with a nullable optional paramter from an AngularJS controller. It works fine if I provide the parameter value but don't work if the parameter value is not provided!! and shows he following error:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
and In details:
System.InvalidOperationException: Missing parameter: name.
at System.Web.Services.Protocols.ValueCollectionParameterReader.Read(NameValueCollection collection)
at System.Web.Services.Protocols.UrlParameterReader.Read(HttpRequest request)
at System.Web.Services.Protocols.HttpServerProtocol.ReadParameters()
at System.Web.Services.Protocols.WebServiceHandler.CoreProcessRequest()
Here is Web service Method:
[WebMethod]
public void GetAllStudents(string name)
{
IQueryable<Student> listStudents = dbContext.Students;
if (!String.IsNullOrEmpty(name))
{
listStudents = listStudents.Where(x => x.name.Contains(name));
}
JavaScriptSerializer js = new JavaScriptSerializer();
Context.Response.Write(js.Serialize(listStudents.ToList()));
}
Here is My Route Config:
$routeProvider.when("/students/:name?",
{
templateUrl: "Templates/Students.html",
controller: "studentsController",
})
Here is My Controller:
.controller("studentsController", function ($scope, $http, $route, $location, $routeParams) {
$scope.message = "Student Page";
$scope.studentSearch = function () {
if ($scope.name) {
$location.url("/students/" + $scope.name);
}
else {
$location.url("/students");
}
}
if ($routeParams.name) {
$http({
method: "GET",
url: "StudentService.asmx/GetAllStudents",
params: { name: $routeParams.name }
})
.then(function (response) {
$scope.students = response.data;
})
}
else {
$http.get("StudentService.asmx/GetAllStudents")
.then(function (response) {
$scope.students = response.data;
})
}
})
*Any Help please!!
It works but looks a bit of ugly with two if statement successively
if ($routeParams.name) {
$http({
method: "GET",
url: "StudentService.asmx/GetAllStudents",
params: { name: $routeParams.name }
})
.then(function (response) {
$scope.students = response.data;
})
}
if ($routeParams.name == undefined) {
$http({
method: "GET",
url: "StudentService.asmx/GetAllStudents",
params: { name: ""}
})
.then(function (response) {
$scope.students = response.data;
})
}
instead of write if else statement just check that param before sending and assign null if there is no value in that or if it is undefined
$routeParams.name = (!angular.isUndefined($routeParams.name) && $routeParams.name != "")?$routeParams.name:"";
$http({
method: "GET",
url: "StudentService.asmx/GetAllStudents",
params: { name: $routeParams.name }
})
.then(function (response) {
$scope.students = response.data;
})
}

how to get the data before loading the page in angularjs providers

I have a requirement like to get the data before loading the page by using angular js providers ,am not implement it please anybody help me.
This is my code please go through it
hiregridApp.provider('organizationService', function() {
return {
getOrganization: ['$http', '$location',
function($http, $location) {
$http({
method: 'GET',
url: http: //dev.api.hiregrid.io/api/customer/token/hiregrid',
}).success(function(data) {
$log.log(data);
}).error(function(error, status) {
$routeParams.code = status;
$location.path('/error/' + $routeParams.code);
});
}
]
}, this.$get: ['$http', '$location',
function($http, $location) {
var obj = '';
alert("hai");
obj.getOrganization = function() {
$http({
method: 'GET',
url: 'http://dev.api.hiregrid.io/csbuilder- api/api/csbuilder/hiregrid',
}).success(function(data) {
$log.log(data);
}).error(function(error, status) {
$routeParams.code = status;
$location.path('/error/' + $routeParams.code);
});
return obj;
}
}
];
});
hiregridApp.config(function(organizationServiceProvider) {
console.log(organizationServiceProvider);
organizationServiceProvider.getOrganization("http://dev.api.hiregrid.io");
});
You could resolve your data in routing so when ever you navigate to a page it will resolve your data and then navigate.
Note if server take long time to response so it will not navigate u till it has resolved your promise.
You can use your provider in config where you have your router configuration.
angular.module ('app',[]).config (function(yourProvider){})
var config = { headers : {'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8;'}};
App.provider('organizationService', ['$http',
function($http) {
return {
getOrganization: function (){
$http.get("http: //dev.api.hiregrid.io/api/customer/token/hiregrid",config)
.success(function(data) {
$log.log(data);
}).error(function(error, status) {
$routeParams.code = status;
$location.path('/error/' + $routeParams.code);
});
}
}
}
]);
If you want to load data before page loaded, use resolve inside your router. For that you don't need providers.
About resolve you can read here angular router

AngularJS: console.log does not display anything

I wrote a controller for login page. Here is my controller:
var authApp = angular.module('loginApp', [])
authApp.controller('LoginCtrl', ['$scope', '$location', 'loginFactory', function($scope, $location, loginFactory){
$scope.authenticate = function() {
loginFactory.login($scope.username, $scope.password)
.then(function(response) {
console.log(response.$statusText);
}, function errorCallBack(response) {
console.log(response.$statusText);
});
}
}]);
My service:
authApp.factory("loginFactory", function ($http) {
return{
login: function(username, password) {
var data = "username="+username+"&password="+password+"&submit=Login";
return $http({
method: 'POST',
url: 'http://localhost:8080/login',
data: data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
});
}
When I debug the code, authentication seems successful and it did get into then function. However nothing displays in console. And I got a warning(?) saying undefined for the line console.log(response.$statusText);. It is not an error since it is not red. Why doesn't it print out anything?
Use response.statusText not response.$statusText. The documentation for AngularJS $http requests lists statusText as one of the properties of the response object - https://docs.angularjs.org/api/ng/service/$http

AngularJS passing data to $http.get request

I have a function which does a http POST request. The code is specified below. This works fine.
$http({
url: user.update_path,
method: "POST",
data: {user_id: user.id, draft: true}
});
I have another function for http GET and I want to send data to that request. But I don't have that option in get.
$http({
url: user.details_path,
method: "GET",
data: {user_id: user.id}
});
The syntax for http.get is
get(url, config)
An HTTP GET request can't contain data to be posted to the server. However, you can add a query string to the request.
angular.http provides an option for it called params.
$http({
url: user.details_path,
method: "GET",
params: {user_id: user.id}
});
See: http://docs.angularjs.org/api/ng.$http#get and https://docs.angularjs.org/api/ng/service/$http#usage (shows the params param)
You can pass params directly to $http.get() The following works fine
$http.get(user.details_path, {
params: { user_id: user.id }
});
Starting from AngularJS v1.4.8, you can use
get(url, config) as follows:
var data = {
user_id:user.id
};
var config = {
params: data,
headers : {'Accept' : 'application/json'}
};
$http.get(user.details_path, config).then(function(response) {
// process response here..
}, function(response) {
});
Solution for those who are interested in sending params and headers in GET request
$http.get('https://www.your-website.com/api/users.json', {
params: {page: 1, limit: 100, sort: 'name', direction: 'desc'},
headers: {'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
}
)
.then(function(response) {
// Request completed successfully
}, function(x) {
// Request error
});
Complete service example will look like this
var mainApp = angular.module("mainApp", []);
mainApp.service('UserService', function($http, $q){
this.getUsers = function(page = 1, limit = 100, sort = 'id', direction = 'desc') {
var dfrd = $q.defer();
$http.get('https://www.your-website.com/api/users.json',
{
params:{page: page, limit: limit, sort: sort, direction: direction},
headers: {Authorization: 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}
}
)
.then(function(response) {
if ( response.data.success == true ) {
} else {
}
}, function(x) {
dfrd.reject(true);
});
return dfrd.promise;
}
});
You can even simply add the parameters to the end of the url:
$http.get('path/to/script.php?param=hello').success(function(data) {
alert(data);
});
Paired with script.php:
<? var_dump($_GET); ?>
Resulting in the following javascript alert:
array(1) {
["param"]=>
string(4) "hello"
}
Here's a complete example of an HTTP GET request with parameters using angular.js in ASP.NET MVC:
CONTROLLER:
public class AngularController : Controller
{
public JsonResult GetFullName(string name, string surname)
{
System.Diagnostics.Debugger.Break();
return Json(new { fullName = String.Format("{0} {1}",name,surname) }, JsonRequestBehavior.AllowGet);
}
}
VIEW:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script type="text/javascript">
var myApp = angular.module("app", []);
myApp.controller('controller', function ($scope, $http) {
$scope.GetFullName = function (employee) {
//The url is as follows - ControllerName/ActionName?name=nameValue&surname=surnameValue
$http.get("/Angular/GetFullName?name=" + $scope.name + "&surname=" + $scope.surname).
success(function (data, status, headers, config) {
alert('Your full name is - ' + data.fullName);
}).
error(function (data, status, headers, config) {
alert("An error occurred during the AJAX request");
});
}
});
</script>
<div ng-app="app" ng-controller="controller">
<input type="text" ng-model="name" />
<input type="text" ng-model="surname" />
<input type="button" ng-click="GetFullName()" value="Get Full Name" />
</div>
For sending get request with parameter i use
$http.get('urlPartOne\\'+parameter+'\\urlPartTwo')
By this you can use your own url string

Categories