Angular Service dont stores boolean - angularjs

I have an angular Service:
presence.service('AuthService', function($http, PresenceURLService){
var apiURL = PresenceURLService.apiURL;
this.isLogged = false,
this.access_token = "",
this.login = function(credentials, callback){
var configura = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
}
};
$http({
method:'POST',
url: apiURL+'login',
data: credentials,
config: configura
}).then(function(response){
//success
this.isLogged = response.data.response;
this.access_token = response.data.access_token;
callback(response.data);
}, function(response){
//error
callback(response.data);
});
}
});
Whenever an user tries to login, the API returns tru or false and it is stored in this.isLogged. Works fine.
I have this code on run for the app, in order to stop the state load if the user is not logged:
presence.run(function($rootScope, $location, $state, AuthService) {
$rootScope.$on( '$stateChangeStart', function(e, toState , toParams, fromState, fromParams) {
var isLogin = toState.name === "login";
if(isLogin){
return; // no need to redirect
}
console.log("State we are going to: "+toState.name);
// now, redirect only not authenticated
var logged = AuthService.isLogged;
console.log("Before load must check the AuthService isLogged var: "+logged);
if(logged === false) {
e.preventDefault(); // stop current execution
$state.go('login'); // go to login
}
});
});
In this code logged is always false. But, previously, when I call login() function, it is stored true.
Why it losses the data and how to obtain this behaviour?

This is because context in which you set isLogged is not AuthService. Read more here how this works
Try this instead:
presence.service('AuthService', function($http, PresenceURLService){
var that = this; // In order to access correct context within callback
var apiURL = PresenceURLService.apiURL;
this.isLogged = false,
this.access_token = "",
this.login = function(credentials, callback){
var configura = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
}
};
$http({
method:'POST',
url: apiURL+'login',
data: credentials,
config: configura
}).then(function(response){
//success
// Use that instead of this here. As this doesn't refers to AuthService
that.isLogged = response.data.response;
that.access_token = response.data.access_token;
callback(response.data);
}, function(response){
//error
callback(response.data);
});
}
});

Related

angularjs redircet to login page if not login

I am using Laravel angularjs
I am using this package https://github.com/andbet39/tokenAuth
it's working fine but my problem is without login i can go to any page also once i reload the page user name is disabled
I don't know what is the problem here
app.js
var app = angular.module('todoApp', ['ui.router', 'satellizer'])
.config(function($stateProvider, $urlRouterProvider, $authProvider,$provide) {
$authProvider.loginUrl = '/api/authenticate';
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login', {
url: '/login',
templateUrl: '/js/tpl/login.html',
controller: 'AuthController'
})
.state('register', {
url: '/register',
templateUrl: '/js/tpl/register.html',
controller: 'AuthController'
})
.state('todo', {
url: '/todo',
templateUrl: '/js/tpl/todo.html',
controller: 'TodoController'
});
function redirectWhenLoggedOut($q, $injector) {
return {
responseError: function (rejection) {
var $state = $injector.get('$state');
var rejectionReasons = ['token_not_provided', 'token_expired', 'token_absent', 'token_invalid'];
angular.forEach(rejectionReasons, function (value, key) {
if (rejection.data.error === value) {
localStorage.removeItem('user');
$state.go('login');
}
});
return $q.reject(rejection);
}
}
}
$provide.factory('redirectWhenLoggedOut', redirectWhenLoggedOut);
});
TodoController.js
app.controller('TodoController', function($state,$http,$rootScope, $scope,$auth) {
$scope.todos=[];
$scope.newTodo={};
$scope.init = function (){
$http.get('/api/todo').success(function(data){
$scope.todos=data;
})
};
$scope.save = function(){
$http.post('/api/todo',$scope.newTodo).success(function (data) {
$scope.todos.push(data);
$scope.newTodo={};
});
};
$scope.update = function(index){
$http.put('/api/todo/'+ $scope.todos[index].id,$scope.todos[index]);
};
$scope.delete = function(index){
$http.delete('/api/todo/'+ $scope.todos[index].id).success(function(){
$scope.todos.splice(index,1);
});
};
$scope.logout = function() {
$auth.logout().then(function() {
localStorage.removeItem('user');
$rootScope.authenticated = false;
$rootScope.currentUser = null;
});
}
$scope.init();
});
AuthController.js
app.controller('AuthController', function($auth, $state,$http,$rootScope, $scope) {
$scope.email='';
$scope.password='';
$scope.newUser={};
$scope.loginError=false;
$scope.loginErrorText='';
$scope.login = function() {
var credentials = {
email: $scope.email,
password: $scope.password
}
$auth.login(credentials).then(function() {
return $http.get('api/authenticate/user');
}, function(error) {
$scope.loginError = true;
$scope.loginErrorText = error.data.error;
}).then(function(response) {
// var user = JSON.stringify(response.data.user);
// localStorage.setItem('user', user);
$rootScope.authenticated = true;
$rootScope.currentUser = response.data.user;
$scope.loginError = false;
$scope.loginErrorText = '';
$state.go('todo');
});
}
$scope.register = function () {
$http.post('/api/register',$scope.newUser)
.success(function(data){
$scope.email=$scope.newUser.email;
$scope.password=$scope.newUser.password;
$scope.login();
})
};
});
I want to redirect to login page if authandicate is falied
How to fix this ?
In angularjs 1.4+ there is no
$http.get('/api/todo').success(function(data){
$scope.todos=data;
})
What you should do instead
$http.get('/api/todo').then(function(data){
$scope.todos=data;
})
And same with this $http.post which you have below.
Also after refreshing page rootScope is deleted and that is why nickname is blank after refresh.
You probably want to store nickname in localStorage or async promise based localForage.
If you chose async localForage on login you can emit custom event with rootScope and execute some function on this event which gather nickname from localForage. You might want to execute this function in some external controller which would wrap all app so when you assign $scope.nick you will have access to it across entire app. Same with $scope.auth = true, you will be able to build your app basing on this boolean for logged in using ng-if directive.
Inject $location to your controller as function parameter and try to redirect like so
$location.path('/todo' );
or
$location.url(YOUR_URL);
Also I don't really understand why you are doing two backend call for login, one inside another. You probably should do one $http.post which would return token in response. Then you could fix and simplify your function code to
$scope.login = function() {
var credentials = {
email: $scope.email,
password: $scope.password
}
$auth.login(credentials).then(function(response) {
$rootScope.authenticated = true;
$rootScope.currentUser = response.data.user;
$scope.loginError = false;
$scope.loginErrorText = '';
}, function(error) {
$scope.loginError = true;
$scope.loginErrorText = error.data.error;
$location.path('/todo' );
});
}
However I don't know your code from $auth service.
Remember to inject $location service.
redirectWhenLoggedOut seems to be an http interceptor.
I think the idea is that you redirect when the http call was not successful. So you need to add an http interceptor that catches the http error and redirects to the login page.
$httpProvider.interceptors.push('redirectWhenLoggedOut');
Don't forget to inject the $httpProvider;

Angularjs $http then is not working properly

I get a value of "True" in my response. How come my debugger and alert and AccessGranted() in the .then of my $http is not being invoked. Below is my Script:
app.controller("LoginController", function($scope, $http) {
$scope.btnText = "Enter";
$scope.message = "";
$scope.login = function() {
$scope.btnText = "Please wait...";
$scope.message = "We're logging you in.";
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
}).then(function (response) {
debugger;
alert(response.data);
if (response.data == "True") {
AccessGranted();
} else {
$scope.message = response.data;
$scope.btnText = "Enter";
}
},
function (error) {
$scope.message = 'Sending error: ' + error;
});
}
$scope.AccessGranted = function() {
window.location.pathname("/Home/HomeIndex");
}
});
This is in my HomeController
public ActionResult HomeIndex()
{
var am = new AuditManager();
var auditModel = new AuditModel()
{
AccountId = 0,
ActionDateTime = DateTime.Now,
ActionName = "Home",
ActionResult = "Redirected to Home"
};
am.InsertAudit(auditModel);
return View("Index");
}
Please see image for the response I get.
seems like your approach is wrong
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Try this,
$http({
method: 'post',
url: '/Login/Login',
data: $scope.LoginUser
})
.then(function (response) {
console.log(response);
},
function (error) {
console.log(error);
});
And check your browser console for logs or any errors
Make sure the response is application/json content type, and content is json.
You can also write own httpProvider for check result from server
module.config(['$httpProvider', function ($httpProvider) {
...
I would suggest you to code like this instead of then so whenever there is success, The success part will be invoked.
$http.get('/path/').success(function (data) {
$scope.yourdata = data.data;
//console.log($scope.yourdata);
}).error(function (error){
//error part
});

Ionic logout not clearing http service data

when I click logout button, its changing the state, but not refreshing the page, because of this, my login page text boxes still having entered data. and If i loggIn with new data, Property details http request not pulling the new data.
I tried, $location.path , $state.go but no use,
can any one help me please.
Login controller
.controller('LoginCtrl', function($scope, $rootScope, AuthenticationService,ClientDetails, $ionicPopup, $state) {
$scope.data = { clientId: '', lastName: '', email: ''};
$scope.login = function () {
AuthenticationService.Login($scope.data.clientId, $scope.data.lastName, $scope.data.email, function(response) {
if(response.success) {
ClientDetails.setDetails(response.data);
$state.go('app.home');
console.log(response);
} else {
$scope.error = response.message;
var alertPopup = $ionicPopup.alert({
title: 'Login failed!',
template: $scope.error
});
}
});
};
})
getting properties through service:
.factory('PropertyDetails',
['$http', '$rootScope',
function ( $http, $rootScope) {
var clientId = $rootScope.globals.clientDetails.ClientId;
var service = {};
service.getProperties = function(callback){
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
var data = ''; var status = ''; var message = '';
var response = {};
var Request = $http({
method: 'GET',
url: 'http://example.com/'+clientId,
data: data
})
Request.success(function(jdata, headers) {
if( headers === 200 ){
if(typeof jdata == 'object'){
status = jdata.Status;
message = jdata.Message;
data = jdata.Data;
$rootScope.globals.properties = data;
}else{
status = false;
message = "Response data is not a object!";
}
}else{
status = false;
message = "Something went wrong!";
}
//response = { success : status, message : message, data: data };
response = { success : status, message : message, data: $rootScope.globals.properties };
callback(response);
//callback($rootScope.globals.properties);
})
Request.error(function(data, headers){
if(typeof data == 'object'){
message = data.Message;
}else{
message = "Client not found.";
}
response = { success : false, message : message };
callback(response);
});
};
service.clearDetails = function(){
$rootScope.globals.properties = {};
};
return service;
}])
My logout controller:
.controller('menuCtrl', function($scope, $rootScope, ClientDetails, PropertyDetails,$timeout,$ionicHistory, $state,$location){
$scope.logOut = function(){
ClientDetails.clearDetails();
PropertyDetails.clearDetails();
$timeout(function () {
$ionicHistory.clearCache();
$ionicHistory.clearHistory();
$ionicHistory.nextViewOptions({ disableBack: true, historyRoot: true });
$state.go('login');
}, 30);
}
})
Thank you
Many Way to clear textbox first of controller call one time to load in ionic if you want to reload again data you used
$scope.$on('$ionicView.enter', function() {
//here some code
});
above code when you open page this code is running every time[load controller].
its simple way.

How to do error handling when fetching data in angularjs service

This code fetches categories and give them to controller.
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function() {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
if ( SuperCategories.length == 0 ) {
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
});
}else {
return $q.when(SuperCategories);
}
}
return SCService;
});
I think code is perfect until there is no error in http request.
My query is how to do error handling (try catch or something like that), in case if server have some issue or may be cgi-script have some issue and not able to server the request.
Angular promises use a method catch for that.
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
});
You should use also finally :
return $http(req).then(function (response) {
SuperCategories = response.data;
return SuperCategories;
}).catch(function(error) {
// Do what you want here
}).finally(function() {
// Always executed. Clean up variables, call a callback, etc...
});
Write like
return $http(req).then(function (response) {
//success callback
},
function(){
//Failure callback
});
Use callback methods from controller Like
Controller.js
service.GetSuperCategories(function (data) {console.log('success'},function (error){console.log('error'});
service.js
sampleApp.factory('SCService', function($http, $q) {
var SuperCategories = [];
var SCService = {};
SCService.GetSuperCategories = function(successMethod,errorMethod) {
var req = {
method: 'POST',
url: SuperCategoryURL,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "action=GET"
};
return $http(req).then(successMethod(data),
errorMethod(error));
}
return SCService;
});
You can use the .success and .error methods of $http service, as below
$http(req).success(function(data, status, headers){
// success callback: Enters if status = 200
}).error(function(status, headers){
// error callback: enters otherwise
});

Creating a user session with AngularJS and DreamFactory

I'm trying to make a simple login function for my AngularJS application. I'm using Dream Factory for my backend server database and I can't seem to be able to create a session from my login-function.
This is the factory I have set up:
dfdevApp.factory('SessionService', function($resource, $q) {
var sessionResource = $resource('https://dsp-myusername.cloud.dreamfactory.com/rest/user/session', {},
{ update: { method: 'PUT' }, query: {method: 'GET', isArray: false} });
return {
create: function (user) {
var deferred = $q.defer();
sessionResource.save(user, function (result) {
deferred.resolve(result);
}, function (error) {
deferred.reject(error);
});
return deferred.promise;
}
}
});
And this is the code from my controller:
// $scope.ting = Liste.get()
$scope.user = {'email' : '', 'password': ''};
$scope.login = function() {
console.log(JSON.stringify($scope.user));
$scope.user = SessionService.create(JSON.stringify($scope.user), function(success) {
$rootScope.loggedIn = true;
$location.path('/');
}, function(error) {
$scope.loginError = true;
});
};
});
I get a 400 every time I try to post.
Your post should be like this one:
{"email":"you#youremail.com","password":"yourpassword"}
Also don't forget to include your app_name in the URL or as a header (in this case, call it X-DreamFactory-Application-Name).
You can find more info here:
http://blog.dreamfactory.com/blog/bid/326379/Getting-Started-with-the-DreamFactory-API
I also built an "SDK" which handles all this for you.
https://github.com/dreamfactorysoftware/javascript-sdk

Resources