Im currently using Ionic and was playing with a app with tabs. (I.e has a bottom bar with icons).
Right now I want to remove it but ended messing up the routing. The devtools does not show any errors. I cannot transit from login page to main "posts" page. On login, clicking the login button does do anything. I have edited the state.go('') in the controllers accordingly.
Ill show before and after the changes.
Would it make sense to remove views :{} totally? I find it complicates things and I do not use nested views. Not sure if modal page requires views.
Appreciate some help/ advice on how to get around the error.
Before
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
// --------Authenticate states ----------------
.state('auth', {
url: '/auth',
templateUrl: 'templates/auth.html',
controller: 'StartCtrl'
})
.state('register', {
url: '/register',
templateUrl: 'templates/register.html',
controller: 'AuthCtrl',
})
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'AuthCtrl',
})
// ---------- Main states ---------------------
.state('tab.posts', {
url: '/posts',
views: {
'tab-posts': {
templateUrl: 'templates/tab-posts.html',
controller: 'PostsCtrl'
}
}
})
.state('tab.newpost', {
url: '/newpost',
views: {
'tab-posts': {
templateUrl: 'templates/tab-newpost.html',
controller: 'NavCtrl'
}
}
})
.state('tab.posts.view', {
url: '/posts/:postId',
views: {
'tab-posts#tab': {
templateUrl: 'templates/tab-showpost.html',
controller: 'PostViewCtrl'
}
}
})
.state('tab.profile', {
url: '/users/:userId',
views: {
'tab-posts': {
templateUrl: 'templates/tab-profile.html',
controller: 'ProfileCtrl',
}
}
})
After
.state('/', {
url: '/',
abstract: true,
templateUrl: 'templates/tab-posts.html'
})
// --------Authenticate states ----------------
.state('auth', {
url: '/auth',
templateUrl: 'templates/auth.html',
controller: 'StartCtrl'
})
.state('register', {
url: '/register',
templateUrl: 'templates/register.html',
controller: 'AuthCtrl',
resolve: {
user: function(Auth){
return Auth.resolveUser();
}
}
})
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'AuthCtrl',
resolve: {
user: function(Auth){
return Auth.resolveUser();
}
}
})
//----------- Main states--------------------
.state('posts', {
url: '/posts',
views: {
'posts': {
templateUrl: 'templates/tab-posts.html',
controller: 'PostsCtrl'
}
}
})
.state('newpost', {
url: '/newpost',
views: {
'posts': {
templateUrl: 'templates/tab-newpost.html',
controller: 'NavCtrl'
}
}
})
.state('posts.view', {
url: '/posts/:postId',
views: {
'posts#': {
templateUrl: 'templates/tab-showpost.html',
controller: 'PostViewCtrl'
}
}
})
.state('profile', {
url: '/users/:userId',
views: {
'posts': {
templateUrl: 'templates/tab-profile.html',
controller: 'ProfileCtrl',
}
}
});
Updated for Levi
app.factory('Auth', function($firebase, $firebaseAuth, FIREBASE_URL, $rootScope) {
var ref = new Firebase(FIREBASE_URL);
var auth = $firebaseAuth(ref);
var Auth = {
register: function (user) {
return auth.$createUser(user.email, user.password);
},
login: function (user) {
return auth.$authWithPassword(user);
},
logout: function() {
auth.$unauth();
},
resolveUser: function() {
return auth.$waitForAuth();
},
signedIn: function() {
return !!Auth.user.provider;
},
createProfile: function (user) {
var profile = {
username: user.username,
md5_hash: user.md5_hash
};
var profileRef = $firebase(ref.child('profile'));
return profileRef.$set(user.uid, profile);
},
user: {}
};
auth.$onAuth(function (user){
if(user) {
angular.copy(user, Auth.user);
Auth.user.profile = $firebase(ref.child('profile').child(Auth.user.uid)).$asObject();
console.log(Auth.user);
} else {
console.log('logged out');
if (Auth.user && Auth.user.profile) {
Auth.user.profile.$destroy();
}
angular.copy({}, Auth.user);
}
});
return Auth;
});
Image for error trace
Remove you resolver from your login state.
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'AuthCtrl',
})
If a someone want to go to login, you can't force him to be logged in.
Related
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;
}
In my app I am trying to dashboard.html and associated controller would load if the condition is true, but the problem is first time it will load the controller but from second time it is opening html page but not only loading controller.
What may the wrong where I did mistake please help me to find.
app.js
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
})
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'templates/menu.html',
controller: 'AutoLoginCtrl'
})
.state('app.autoLog', {
url: '/autoLog',
controller: 'AutoLoginCtrl'
})
.state('app.search', {
url: '/search',
views: {
'menuContent': {
templateUrl: 'templates/search.html'
}
}
})
.state('app.browse', {
url: '/browse',
views: {
'menuContent': {
templateUrl: 'templates/browse.html'
}
}
})
.state('app.profileInfo', {
url: '/profileInfo/:success',
views: {
'menuContent': {
templateUrl: 'templates/profileInfo.html',
controller: 'ProfileCtrl'
}
}
})
.state('app.profile', {
url: '/profile/:data',
views: {
'menuContent': {
templateUrl: 'templates/profile.html',
controller: 'ProfileCtrl'
}
}
})
.state('app.dashboard', {
url: '/dashboard',
views: {
'menuContent': {
templateUrl: 'templates/dashboard.html'
}
}
})
.state('app.dog', {
url: '/dog',
views: {
'menuContent': {
templateUrl: 'templates/dog.html',
controller: 'ProfileCtrl'
}
}
});
$urlRouterProvider.otherwise('/app/autoLog');
loginController.js
If the below condition is true then is will call .state('app.dashboard')
if (data[0].Userprofile1 == true && data[0].Userprofile2 == true) {
$ionicLoading.hide();
console.log('My profile setup is over');
$state.go("app.dashboard");
}
dashboardController.js
app.controller('dashboardCtrl', function($scope, $http, $state, UserService) {
$scope.pageName = 'Hi i am user';
console.log('Hi home controller loading')
var userStatus = UserService.getUser()
console.log(userStatus);
if (userStatus != null) {
$scope.ersrserer = userStatus.userID;
console.log($scope.ersrserer);
} else {
console.log('its empty');
}
})
first time when it calls dashboard.html it will load controller also but from second time it will not load controller, what went wrong here?
A state requires a controller to be initialized with it, you have add the controller and inside the state you can add a resolve block:
.state('your state', {
url: '/url',
resolve: {
someName: function(inject here) {
//return something, or redirect to a state...etc
}
},
templateUrl: 'templates/something.html',
controller: 'ExampleCtrl'
})
I am new to the ionic framework.
I am working on an app and I don't want tabs in the landing page.
How to hide tabs on landing page (Home page) in ionic.
In the below example its working when you click on the Scientific Facts, I am not getting how to do it can any one please help me with this issue.
Example
angular.module('ionicApp', ['ionic'])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('tabs', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
.state('tabs.home', {
url: "/home",
views: {
'home-tab': {
templateUrl: "templates/home.html",
controller: 'HomeTabCtrl'
}
}
})
.state('tabs.facts', {
url: "/facts",
views: {
'home-tab': {
templateUrl: "templates/facts.html"
}
}
})
.state('tabs.facts2', {
url: "/facts2",
views: {
'home-tab': {
templateUrl: "templates/facts2.html"
}
}
})
.state('tabs.about', {
url: "/about",
views: {
'about-tab': {
templateUrl: "templates/about.html"
}
}
})
.state('tabs.navstack', {
url: "/navstack",
views: {
'about-tab': {
templateUrl: "templates/nav-stack.html"
}
}
})
.state('tabs.contact', {
url: "/contact",
views: {
'contact-tab': {
templateUrl: "templates/contact.html"
}
}
});
$urlRouterProvider.otherwise("/tab/home");
})
.controller('HomeTabCtrl', function($scope) {
console.log('HomeTabCtrl');
})
.directive('hideTabs', function($rootScope) {
return {
restrict: 'A',
link: function($scope, $el) {
$rootScope.hideTabs = 'tabs-item-hide';
$scope.$on('$destroy', function() {
$rootScope.hideTabs = '';
});
}
};
});
I just had a similar problem... try making the Home page a separate state/template/controller outside of the nested tabs.logic. The easiest way I found to do this was in two steps:
Remove your Home from the nested .state('tabs.home', logic to just .state('home',
Remove the views: { portion and just add the templateUrl and
controller directly.
(I also moved it to the top of the list for clarity)
I've modified the code below as an example:
$stateProvider
.state('home', {
url: "/home",
templateUrl: "templates/home.html",
controller: 'HomeTabCtrl'
})
//everything below here is the same, but I left it for context
.state('tabs', {
url: "/tab",
abstract: true,
templateUrl: "templates/tabs.html"
})
.state('tabs.facts', {
url: "/facts",
views: {
'home-tab': {
templateUrl: "templates/facts.html"
}
}
})
Hi i am new to ionic framework. i am using session manager in ionic. But i want to skip login page if user is already logged in.
app.js
angular.module('grocery', ['ionic', 'grocery.controller', 'ngCordova', 'ngCordovaOauth'])
.run(function($ionicPlatform, $cordovaSQLite, $cordovaToast, $rootScope, mainItemsList, $state) {
$ionicPlatform.ready(function() {
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
});
$rootScope.$on('$locationChangeStart', function(event, newUrl, oldUrl) {
if (mainItemsList.isLoggedIn() != true) {
$state.go('app.login');
}
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/navigationDrawer.html",
controller: 'AppCtrl'
})
.state('app.masterList', {
url: "/masterList",
views: {
'menuContent': {
templateUrl: "templates/masterList.html",
controller: 'indexCtrl'
}
}
})
.state('app.login', {
url: "/login",
views: {
'menuContent': {
templateUrl: "templates/login.html",
controller: 'loginCtrl'
}
}
})
.state('app.register', {
url: "/register",
views: {
'menuContent': {
templateUrl: "templates/register.html",
controller: 'registerCtrl'
}
}
})
$urlRouterProvider.otherwise("/app/masterList");
});
angular.module('grocery.services', [])
.factory('mainItemsList', function($cordovaSQLite, $cordovaToast, $cordovaPreferences) {
return {
isLoggedIn: function(sessionEmail) {
$cordovaPreferences.store('email', sessionEmail).success(function(value) {
//$cordovaToast.showShortTop('stored');
})
.error(function(error) {
$cordovaToast.showShortTop("Error " + error);
})
return true;
}
}
})
I tried existing stackoverflow answers. But not working. please help me where i am wrong.
Create a new controller and a new state called autologin. Make this your default state. In the autologin controller, check whether the user is already logged in. If he is, redirect to some page. If he is not, redirect to login.
.state('app.autologin', {
url: "/autologin",
controller: 'autologinCtrl'
})
$urlRouterProvider.otherwise("/app/autologin");
controller:
angular.module('grocery').controller('autologinCtrl, function($scope, $state){
//check if user is logged in
if (userLoggedIn){
state.go('app.masterList');
} else {
state.go('app.login');
}
});
If you are adding a new controller for this logic,There will be a chance for flickering between the pages.So handle this by using $urlRouterProvider
.config(function($stateProvider, $urlRouterProvider, mainItemsList) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/navigationDrawer.html",
controller: 'AppCtrl'
})
.state('app.masterList', {
url: "/masterList",
views: {
'menuContent': {
templateUrl: "templates/masterList.html",
controller: 'indexCtrl'
}
}
})
.state('app.login', {
url: "/login",
views: {
'menuContent': {
templateUrl: "templates/login.html",
controller: 'loginCtrl'
}
}
})
.state('app.register', {
url: "/register",
views: {
'menuContent': {
templateUrl: "templates/register.html",
controller: 'registerCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise(function() {
var logged = mainItemsList.isLoggedIn();
// Check User logined or not
if (logged != true) {
return 'app.login';
} else {
return 'app.masterList';
}
});
});
So I have my login screen where I do a Facebook login (this works perfect) and upon success of FB login it should go to another view. I try to achieve this with
$state.go("app.start")
But its not working. It just stays on the login view. Not sure why my $state.go is not working ...
My controller for the login button:
angular.module('MovieBankUser.controllers', [])
.controller('LoginCtrl', function($scope, LoginService, $state) {
$scope.loggingIn = false;
$scope.login = function () {
if (!$scope.loggingIn) {
$scope.loggingIn = true;
LoginService.loginUser().then(function () {
$scope.loggingIn = false;
//$window.location.href = "#/app/start"
$state.go('app.start');
//console.log("TEST TEST");
});
}
}
});
Part of my app.js code for the routing:
// Routes
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'views/login/login.html',
controller: 'LoginCtrl'
})
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'components/sidebar_menu/menu.html',
controller: 'AppCtrl'
})
.state('app.start', {
url: '/start',
views: {
'menuContent': {
templateUrl: 'views/start/start.html',
controller: 'MovieCtrl'
}
}
})
.state('app.trending', {
url: '/trending',
views: {
'menuContent': {
templateUrl: 'views/trending/trending.html',
controller: 'MovieCtrl'
}
}
})
.state('app.trending-detail', {
url: '/trending/:id',
views: {
'menuContent': {
templateUrl: 'views/trending/trending_detail.html',
controller: 'MovieDetailCtrl',
resolve: {
movie: function($stateParams, MovieService) {
return MovieService.getMovieById($stateParams.id)
},
trailer: function($stateParams, MovieService) {
return MovieService.getTrailerById($stateParams.id)
},
cast: function($stateParams, MovieService) {
return MovieService.getCastCrewInfo($stateParams.id)
}
}
}
}
})
.state('app.outnow', {
url: '/outnow',
views: {
'menuContent': {
templateUrl: 'views/out_now/outnow.html',
controller: 'MovieCtrl'
}
}
})
.state('app.outnow-detail', {
url: '/outnow/:id',
views: {
'menuContent': {
templateUrl: 'views/out_now/outnow_detail.html',
controller: 'MovieDetailCtrl',
resolve: {
movie: function($stateParams, MovieService) {
return MovieService.getMovieById($stateParams.id)
},
trailer: function($stateParams, MovieService) {
return MovieService.getTrailerById($stateParams.id)
},
cast: function($stateParams, MovieService) {
return MovieService.getCastCrewInfo($stateParams.id)
}
}
}
}
})
.state('app.comingsoon', {
url: '/comingsoon',
views: {
'menuContent': {
templateUrl: 'views/coming_soon/comingsoon.html',
controller: 'MovieCtrl'
}
}
})
.state('app.comingsoon-detail', {
url: '/comingsoon/:id',
views: {
'menuContent': {
templateUrl: 'views/coming_soon/comingsoon_detail.html',
controller: 'MovieDetailCtrl',
resolve: {
movie: function($stateParams, MovieService) {
return MovieService.getMovieById($stateParams.id)
},
trailer: function($stateParams, MovieService) {
return MovieService.getTrailerById($stateParams.id)
},
cast: function($stateParams, MovieService) {
return MovieService.getCastCrewInfo($stateParams.id)
}
}
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/login');
});