Angular distribution app not working as spected - angularjs

I have developed an application with angular, but when I build the distribution application with grunt I have an strange behaviour of my application.
For example:
console.log("START");
AuthService.refresh(LoopBackAuth.accessTokenId).then(function() {
console.log("USER LOADED");
$state.go('main.documents');
});
and in main.documents I have:
console.log("DOCUMENTS");
so the flow should be (the flow that I have in my production files):
log-->START
log-->USER LOADED
log-->DOCUMENTS
but the flow that I get in the production files is the following:
log-->START
log-->DOCUMENTS
log-->USER LOADED
and in my documents view my $rootScope where I save my user details it is empty and it fails all the time.
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider.state('login', {
url: '/login',
templateUrl: 'views/login.html',
controller: 'LoginCtrl',
authenticate: false
});
$stateProvider.state('main', {
abstract: true,
url: '/',
templateUrl: 'views/main.html',
controller: 'MainCtrl',
authenticate: true
});
$stateProvider.state('main.documents', {
url: 'documents',
templateUrl: 'views/main/documents.html',
controller: 'MainDocumentsCtrl',
authenticate: true
});
$stateProvider.state('main.information', {
url: 'information',
templateUrl: 'views/main/managing-information.html',
controller: 'MainInformationCtrl',
authenticate: true
});
$stateProvider.state('main.calendar', {
url: 'calendar',
templateUrl: 'views/main/calendar.html',
controller: 'MainCalendarCtrl',
authenticate: true
});
$stateProvider.state('main.notices', {
url: 'notices',
templateUrl: 'views/main/notices.html',
controller: 'MainNoticesCtrl',
authenticate: true
});
$stateProvider.state('main.settings', {
url: 'settings',
templateUrl: 'views/main/settings.html',
controller: 'MainSettingsCtrl',
authenticate: true
});
$urlRouterProvider.otherwise('login');
}])
User authentication:
.run(['$rootScope', '$state', 'LoopBackAuth', 'Authentication', function($rootScope, $state, LoopBackAuth, AuthService) {
$rootScope.$on('$stateChangeStart', function(event, toState, toParams) {
// redirect to login page if not logged in
if (toState.authenticate && !LoopBackAuth.accessTokenId) {
event.preventDefault();
$rootScope.returnTo = {
state: toState,
params: toParams
};
$state.go('login');
}
});
// Get data from localstorage after pagerefresh
// and load user data into rootscope.
if (LoopBackAuth.accessTokenId && !$rootScope.currentUser) {
console.log("USER LOGGED IN");
AuthService.refresh(LoopBackAuth.accessTokenId).then(function() {
console.log("USER LOADED");
$state.go('main.documents');
});
}
}]);

Related

Ionic 1 - Show login page if user not logged and skip if user is already logged

Working on an Ionic version 1.3.3 application where need following functionalities for user login. I had go through all stackoverflow answer but nothing found a workable solution for me.
App will check on start if user already logged in (check through Ionic $localstorage) then redirect to Home page
If the user is not logged redirect to login page on app start
On login page after login success redirect to home page and clear login page history.
angular.module('starter', ['ionic', 'starter.controllers', 'starter.directives', 'starter.services', 'ngStorage','ab-base64',])
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/app',
abstract: true,
cache: false,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl',
onEnter: function ($state) {
console.log($state);
}
})
.state('app.home', {
cache: false,
url: '/home',
views: {
'menuContent': {
templateUrl: 'templates/home.html'
}
}
})
.state('app.login', {
cache: false,
url: '/login/:username/:password',
views: {
'menuContent': {
templateUrl: 'templates/login.html',
controller: 'LoginController'
}
}
})
.state('app.profile', {
cache: false,
url: '/profile',
views: {
'menuContent': {
templateUrl: 'templates/profile.html',
controller: 'ProfileController'
}
}
})
$urlRouterProvider.otherwise('/app/home');
})
This is how I accomplished this in Ionic v1:
For the redirect if user is logged in:
.state("app.dash", {
url: "/dashboard",
abstract: true,
views: {
mainContent: {
templateUrl: "templates/dashboard.html",
controller: "DashboardCtrl",
controllerAs: "vm",
resolve: {
auth: [
"authService",
function(authService) {
return authService.isAuthenticated();
}
],
permissions: [
"authService",
function(authService) {
return authService.getPermissions();
}
]
}
}
}
})
For the redirect when user logs in or is already logged in.
.state("app.login", {
url: "/login?accountCreated",
views: {
mainContent: {
templateUrl: "templates/login.html",
controller: "LoginCtrl",
controllerAs: "vm",
resolve: {
isLoggedIn: [
"$q",
"$state",
"authService",
function($q, $state, authService) {
authService.isAuthenticated().then(function(res) {
$state.go("app.dash.home");
});
return $q.defer().resolve();
}
]
}
}
}
})
Auth service isAuthenticated()
function isAuthenticated() {
var deferred = $q.defer();
getToken().then(function(token) {
isExpired().then(function(isExpired) {
if (!token || isExpired) {
deferred.reject("Not Authenticated");
} else {
decodeToken().then(function(decodedToken) {
deferred.resolve(decodedToken);
});
}
});
});
return deferred.promise;
}

$state.go is not working when project is run with ionic serve --lab command

Hello I am working with ionic framework and I want to redirect to another page
after successfully login .When I run project using command:
ionic serve then $state.go working properly but when I run project using
ionic serve --lab it is not working
.controller('AppCtrl', function($scope,$http, $ionicModal,$location,$state, $timeout) {
// Form data for the login modal
$scope.loginData = {};
// Create the login modal that we will use later
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: $scope
}).then(function(modal) {
$scope.modal = modal;
});
// Triggered in the login modal to close it
$scope.closeLogin = function() {
$scope.modal.hide();
};
// Open the login modal
$scope.login = function() {
$scope.modal.show();
};
// Perform the login action when the user submits the login form
$scope.doLogin = function() {
alert($scope.loginData.username);
alert($scope.loginData.password);
$http({
method: 'POST',
url: 'http://localhost/home_owner12/admin/api/login',
data: {username:$scope.loginData.username,password:$scope.loginData.password},
headers : {
'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'}
})
.then(function successCallback(response)
{
if(response.data.length > 0)
{
$state.go('app.search');
console.log('the state is '+$state.current);
}
else
{
alert("Invalid email or pasword");
///$location.path('/search');
}
}, function errorCallback(response)
{
alert("Invalid email pasword");
});
};
})
here is state:
config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.search', {
url: '/search',
views: {
'menuContent': {
templateUrl: 'templates/search.html',
controller: 'AppCtrl'
}
}
});
and module
angular.module('starter', ['ionic', 'starter.controllers', 'ui.router'])
The app.search page's controller goes to AppCtrl in place.
Because AppCtrl runs a second time, it is entering an infinite loop.
Replace the code with that
config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.search', {
url: '/search',
views: {
'menuContent': {
templateUrl: 'templates/search.html',
controller: 'SearchCtrl'
}
}
});
and
.controller('SearchCtrl', function($scope,$http, $ionicModal,$location,$state, $timeout) {
............
.........
.......
})

Bestpractice Authentication in AngularJS 1x with ui router

I got a working angular code to successfully get/store/retrieve a jwt token for authentication.
Also I got the following route controller:
// Router configuration
App.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/dashboard');
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl: 'assets/views/dashboard.html'
})
.state('customers', {enter code here
url: '/customers',
templateUrl: 'assets/views/customers.html'
})
.state('customersAdd', {
url: '/customers/add',
templateUrl: 'assets/views/customers_add.html'
})
.state('account', {
url: '/account',
templateUrl: 'assets/views/account.html'
})
.state('login', {
url: '/login',
templateUrl: 'assets/views/login.html'
});
}
]);
I went through different tutorials on the net and I think, for my understanding the best approach would be using resolve on my routes. Yet I don't know how to bring the pieces togehter. I got a working auth service with a function auth.isAuth() that returns true or false.
But how can I bind this into my routes? And also I would like to explicit mark routes that doesn't need auth.isAuth() to be true, because there are only like two states that doesn't require an authenticated user.
Greetings
eXe
Just in case someone is looking for the same, this is my final solution:
// Router configuration
App.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/dashboard');
$stateProvider
.state('auth', {
url: '',
abstract: true,
resolve: {
loginRequired: loginRequired
},
})
.state('auth.dashboard', {
url: '/dashboard',
templateUrl: 'assets/views/dashboard.html'
})
.state('auth.customers', {
url: '/customers',
templateUrl: 'assets/views/customers.html'
})
.state('auth.customersAdd', {
url: '/customers/add',
templateUrl: 'assets/views/customers_add.html'
})
.state('auth.account', {
url: '/account',
templateUrl: 'assets/views/account.html'
})
.state('login', {
url: '/login',
templateUrl: 'assets/views/login.html'
});
}
]);
function loginRequired($q, $location, auth) {
var deferred = $q.defer();
if (auth.isAuthed()) {
deferred.resolve();
} else {
$location.path('/login');
}
return deferred.promise;
}
By using nested states my 'auth' state acts like a middleware. Now I can easily manage my routes.
Here is how I do it. Borrowed from the Satellizer library. Works great!
//note the resolve block.
$stateProvider
.state('home', {
url: '/home',
controller: 'HomeCtrl',
templateUrl: 'views/home.html',
data: {
pageTitle: 'Home'
},
resolve: {
loginRequired: loginRequired
}
})
.state('splash', {
url: '/',
templateUrl: 'views/auth/splash.html',
controller: 'SplashCtrl',
data: {
pageTitle: 'Welcome'
},
resolve: {
skipIfLoggedIn: skipIfLoggedIn
}
})
//add to your apps config block, below your route definitions
function skipIfLoggedIn($q, auth) {
var deferred = $q.defer();
if (auth.isAuth()) {
deferred.reject();
} else {
deferred.resolve();
}
return deferred.promise;
}
function loginRequired($q, $location, auth) {
var deferred = $q.defer();
if (auth.isAuth()) {
deferred.resolve();
} else {
$location.path('/');
}
return deferred.promise;
}

intercept route and redirect to login

Take the following code. I have a cookie that is created once a user successfully logs in. My API is also already authenticated. What I am looking to do is do a simple check of the cookie before serving up a route, with the only exception of the login route.
angular
.module('pizzaGiants.routes', ['ui.router'])
.config(['$stateProvider', '$locationProvider', '$urlRouterProvider',
function ($stateProvider, $locationProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
// Application Routes
// -----------------------------------
// add check if cookie exists else redirect to login
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'features/login/login.html',
controller: 'loginCtrl'
})
.state('attributes', {
url: '/attributes',
templateUrl: 'features/attributes/attributes.html',
controller: 'attributesCtrl'
})
.state('users', {
url: '/users',
templateUrl: 'features/users/users.html',
controller: 'usersCtrl'
})
.state('signup', {
url: '/signup',
templateUrl: 'features/signup/signup.html',
controller: 'signupCtrl'
})
.state('roles', {
url: '/roles',
templateUrl: 'features/roles/roles.html',
controller: 'rolesCtrl'
})
.state("fruits", {url: "/fruits",templateUrl: "features/fruits/fruit.html",controller: "fruitCtrl"}).state("colors", {url: "/colors",templateUrl: "features/colors/color.html",controller: "colorCtrl"}).state("contacts", {url: "/contacts",templateUrl: "features/contacts/contact.html",controller: "contactCtrl"})
}]);
Could be like following
app.run([
'$rootScope','$location', '$timeout',
function ($rootScope, $location, $timeout) {
$rootScope.$on('$stateChangeStart', function () {
if (// your condition logic) {
$timeout(function () {
$location.path("/login");
}, 1);
}
});
}
]);

how to go to state with stateProvider?

Playing around with angular stateProvider, this is my route:
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state("start", {
url: "/",
templateUrl: 'start.html',
controller: 'StartCtrl'
})
.state("test", {
url: "/",
templateUrl: 'test.html',
controller: 'TestCtrl'
});
}]);
On bootstrapping I would like to go to state 'test':
app.run(['$rootScope', '$state', '$stateParams', function ($rootScope, $state, $stateParams) {
$state.go('test');
console.log('app.run');
}]);
These are the controllers:
app.controller('StartCtrl', function($scope) {
console.log('start');
});
app.controller('TestCtrl', function($scope) {
console.log('test');
});
Why is the application routing to the 'start' state ? I would like to go to the 'test' state?
Code reference:http://plnkr.co/edit/FCcL4M?p=preview
You need to change the url for either the test or the start "state", right now they are both the same. I changed the test state url to "/test" and it loaded correctly.
http://plnkr.co/edit/2esV4dbd4ptNSEmwD3g4?p=preview
app.config(['$stateProvider',
function($stateProvider) {
$stateProvider
.state("start", {
url: "/",
templateUrl: 'start.html',
controller: 'StartCtrl'
})
.state("test", {
url: "/test",
templateUrl: 'test.html',
controller: 'TestCtrl'
});
}
]);
Just need to add to previous answer : both start and test need to be corrected
to follow standards.
http://plnkr.co/edit/TjDzyL?p=preview
pp.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state("start", {
url: "/start",
templateUrl: 'start.html',
controller: 'StartCtrl'
})
.state("test", {
url: "/test",
templateUrl: 'test.html',
controller: 'TestCtrl'
});
}]);

Resources