controller is not loading whenever associated html is opened in IONIC V1 - angularjs

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'
})

Related

Clicking a link doesn't redirect? How to debug ui-router?

I scaffolded an ionic V1 site using tab template and created the following link in a page.
<a href="#/tab/Test">
Test
</a>
And an empty control for "Test" page.
.controller('TestCtrl', function ($scope) {
})
The following is the router
.state('tab.test', {
url: '/test',
views: {
'tab-test': {
templateUrl: 'templates/tab-test.html',
controller: 'TestCtrl'
}
}
})
However, when testing using ionic serve, click the link doesn't go to the page. It stays in the page but the URL in the address bar changed to localhost:8100/#/tab/test.
Full router.
.config(function ($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
})
.state('events', {
url: '/events',
templateUrl: 'templates/events.html',
controller: 'EventsCtrl'
})
// setup an abstract state for the tabs directive
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('tab.settings', {
url: '/settings',
views: {
'tab-settings': {
templateUrl: 'templates/tab-settings.html',
controller: 'SettingsCtrl'
}
}
})
.state('tab.test', {
url: '/test',
views: {
'tab-test': {
templateUrl: 'templates/tab-test.html',
controller: 'TestCtrl'
}
}
})
.state('tab.venues', {
url: '/venues',
views: {
'tab-venues': {
templateUrl: 'templates/tab-venues.html',
controller: 'VenuesCtrl'
}
}
})
// Each tab has its own nav history stack:
.state('tab.events', {
url: '/events',
views: {
'tab-events': {
templateUrl: 'templates/tab-events.html',
controller: 'EventsCtrl'
}
}
})
.state('tab.categories', {
url: '/categories',
views: {
'tab-categories': {
templateUrl: 'templates/tab-categories.html',
controller: 'CategoriesCtrl'
}
}
})
.state('tab.chats', {
url: '/chats',
views: {
'tab-chats': {
templateUrl: 'templates/tab-chats.html',
controller: 'ChatsCtrl'
}
}
})
.state('tab.chat-detail', {
url: '/chats/:chatId',
views: {
'tab-chats': {
templateUrl: 'templates/chat-detail.html',
controller: 'ChatDetailCtrl'
}
}
})
.state('tab.account', {
url: '/account',
views: {
'tab-account': {
templateUrl: 'templates/tab-account.html',
controller: 'AccountCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/login');
});
Update:
It will works if I change the router to the following. But it will be full screen and the tabs are gone.
.state('test', {
url: '/test',
templateUrl: 'templates/tab-test.html',
controller: 'TestCtrl'
})
and the link href to href="#/privacy".
Change the href url href="#/test'" instead of href="#/tab/Test"
I am using this code
<ion-tab title="" icon-off="ion-ios-home-outline" icon-on="ion-ios-home" href="#/tab/test" ng-if="userkey">
<ion-nav-view name="tab-test"></ion-nav-view>
</ion-tab>
if you want to navigate
< ion-nav-view name="tab-test">
and state name sould be same
.state('tab.test', {
url: '/test',
views: {
'tab-test': {
templateUrl: 'templates/tab-test.html',
controller: 'TestCtrl'
}
}
})

How to hide tabs on landing page (Home page) in ionic

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"
}
}
})

how to skip login page if user already logged in in ionic

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';
}
});
});

Angular app initialization with asynchronous data

I need to initialize my Angular with some User data that the whole app depends on. Therefore I need the initialization to be resolved before the router kicks in and controllers are initialized.
Currently, I wrote the initialization code in a run() block of the angular module. The initialization involves an asynchronous http request to get user data and the rest of the application relies upon the user data.
How can I ensure that the http request is resolved before the router kicks-in initializing the controllers?
I am using the ui-router.
The initialization consists in the following:
1) get cookie 'userId'
2) get User from server (asynchronous http request, the whole app depends upon the User)
3) set authService.currentUser
this is a sample of the code
.run(['$cookies', 'userApiService', 'authService',
function($cookies, userApiService, authService){
var userId = $cookies.get('userId');
userId = parseCookieValue(userId);
userApiService.getOne(userId).then(function(user){
authService.currentUser = user;
});
}])
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$urlRouterProvider.when('/', '/main');
$stateProvider
.state('login', {
url: '/login',
views: {
'header': {
templateUrl: 'views/header.html',
controller: 'HeaderCtrl'
},
'content': {
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
},
'footer': {
templateUrl: 'views/footer.html',
}
}
})
.state('main', {
url: '/main',
views: {
'content#': {
template: '',
controller: function($state, authService) {
if(!authService.isAuthenticated()) {
$state.go('login');
}
if(authService.isStudent()) {
$state.go('student');
}
if(authService.isAdmin()) {
$state.go('admin');
}
}
}
}
})
.state('student', {
url: '/student',
views: {
'header#': {
templateUrl: 'views/header.html',
controller: 'HeaderCtrl'
},
'content#': {
templateUrl: 'views/student.html',
controller: 'StudentCtrl'
},
'footer#': {
templateUrl: 'views/footer.html',
}
}
})
.state('admin', {
url: '/admin',
views: {
'header#': {
templateUrl: 'views/header.html',
controller: 'HeaderCtrl'
},
'content#': {
templateUrl: 'views/admin.html',
controller: 'AdminCtrl'
},
'footer#': {
templateUrl: 'views/footer.html',
}
}
})
}])
Expanding on someone's comment, you can create a root state that is a parent to all of your other app's states (children to the root). The root state resolves all the user data and then you can inject the user data to any controller or store it in a service.
$stateProvider
.state('root', {
url: '',
abstract: true,
template: '', // some template with header, content, footer ui-views
resolve: {
// fetch user data
}
})
.state('root.login', {
url: '/login',
views: {
'header': {
templateUrl: 'views/header.html',
controller: 'HeaderCtrl'
},
'content': {
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
},
'footer': {
templateUrl: 'views/footer.html',
}
}
})
.state('root.main', {
url: '/main',
views: {
'content#': {
template: '',
controller: function($state, authService) {
if(!authService.isAuthenticated()) {
$state.go('login');
}
if(authService.isStudent()) {
$state.go('student');
}
if(authService.isAdmin()) {
$state.go('admin');
}
}
}
}
})
... // your other states
The key is that all of your app states must be a child of your root state i.e. root.<name> in your state declaration. This will ensure that no other controller starts until your user data is available. For more information on resolve and how to use it read here. Also, parent and child states.

AngularJS UI-router stateprovider issue

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.

Resources