I have an ionic app that I'm trying to build some views for. However, for some reason when I create a unique view-name name, my view doesn't work and it redirects to #/tab/home. The view I'm trying to create is called login, it should be accessed by going to #/tab/login.
Here's my full app.js file.
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.services' is found in services.js
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ui.rCalendar'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.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
// setup an abstract state for the tabs directive
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
})
// Each tab has its own nav history stack:
.state('tab.home', {
url: '/home',
views: {
'tab-home': {
templateUrl: 'templates/tab-home.html',
controller: 'HomeCtrl'
}
}
})
.state('tab.feed', {
url: '/feed',
views: {
'tab-feed': {
templateUrl: 'templates/tab-feed.html',
controller: 'FeedCtrl'
}
}
})
.state('tab.login', {
url: '/login',
views: {
'tab-login': {
templateUrl: 'templates/tab-login.html',
controller: 'LoginCtrl'
}
}
})
.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.events', {
url: '/events',
views: {
'tab-events': {
templateUrl: 'templates/tab-events.html',
controller: 'EventsCtrl'
}
}
})
.state('tab.cart', {
url: '/cart',
views: {
'tab-cart': {
templateUrl: 'templates/tab-cart.html',
controller: 'CartCtrl'
}
}
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tab/login');
});
I've got a file called tab-login.html. When I change the view-name from tab-login to anything else that already exists like tab-feed, when I go to #/tab/login it works fine. So it works when it looks like this:
.state('tab.login', {
url: '/login',
views: {
'tab-feed': {
templateUrl: 'templates/tab-login.html',
controller: 'LoginCtrl'
}
}
})
It works just fine...which makes no sense to me. What am I doing wrong? And why is it redirecting to home when I have it set to default to login?
Related
Am new to the angular js.
Am implementing a nested ui view but the problem is when checking the current state of a page it returns many objects such that i cant use $state.current to set the ng-show
I would like the navbar shown and hidden in some states.
I have tried
The main index.html page
<html>......
<body ng-app="myapp">
<nav ng-controller="headerCtrl" ng-show="shownav()" >
//here is the navbar code..The shownav is defined on the headerCtrl
</nav>
<div ui-view> </div>
//Angular js, controllers and services links
</body>
</html>
The app.js code
var app = angular.module('myApp', ['ui.router']);
app.controller('headerCtrl',function($scope, $state) {
$scope.shownavbar = function(){
var state = $state.current;
if(state ==='login' ){
return false;
}else{
return true;
}
}
app.config(function($stateProvider, $urlRouterProvider, $httpProvider){
$stateProvider
.state('login', {
url:'/login',
templateUrl: 'templates/index/login/login.html',
controller: 'loginCtrl'
})
.state('dash', {
url: '/dash',
templateUrl:'templates/layout/dashboard.html',
abstract:true
})
.state('dash.call',{
url: '/call',
templateUrl: 'templates/index/calls/calls.html',
controller: 'callCtrl'
})
.state('dash.profile', {
url: '/profile',
templateUrl: 'templates/index/account/profile/profile.html',
controller: 'profileCtrl'
})
});
I would like the navbar hidden for some states like when a user is on the login state
At the headerctrl i have also tried
$scope.shownavbar = function(){
var state = $state.current;
$log.info(state);
}
This returns in the console:
angular.js:13708 Object {name: "", url: "^", views: null, abstract: true}
angular.js:13708 Object {name: "", url: "^", views: null, abstract: true}
angular.js:13708 Object {url: "/login", templateUrl: "templates/index/login/login.html", controller: "loginCtrl", name: "login"}
angular.js:13708 Object {url: "/login", templateUrl: "templates/index/login/login.html", controller: "loginCtrl", name: "login"}
angular.js:13708 Object {url: "/login", templateUrl: "templates/index/login/login.html", controller: "loginCtrl", name: "login"}
WHAT COULD BE THE PROBLEM
I can think in two ways to solve this.
First solution
EDITED
inside your run() put a function to see when the state is changing and hide or show the navbar.
myApp.run(function ($rootScope, $state) {
$rootScope.navbar = false;
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
if (toState.name === 'login') {//toState variable see the state you're going
$rootScope.navbar = false;
} else {
$rootScope.navbar = true;
}
});
});
and change in your ng-show="navbar"
Second solution
the second solution i can think is you use multiple views.
$stateProvider
.state('login', {
url: '/',
views: {
'navbar': {
templateUrl: null,
controller: null
},
'body': {
templateUrl: "views/login.html",
controller: 'LoginController'
}
}
})
.state('home', {
url: '/home',
views: {
'navbar': {
templateUrl: "views/navbar.html",
controller: null
},
'body': {
templateUrl: "views/inicio.html",
controller: null
}
}
});
and in your html views put something similar to this:
<div ui-view="navbar"></div>
<div ui-view="body"></div>
This is my index.html:
<body>
<div ui-view></div>
</body>
This is my app.js:
angular.module('sample', [
'auth0',
'ngRoute',
'sample.home',
'sample.header',
'sample.login',
'ui.router',
'angular-storage',
'angular-jwt'
])
.config(function myAppConfig($stateProvider, $urlRouterProvider, $routeProvider, authProvider, $httpProvider, $locationProvider,
jwtInterceptorProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'login/login.html',
controller: 'LoginCtrl'
}).state('root', {
url: '/',
abstract: true,
views: {
'header': {
templateUrl: 'home/header.html',
controller: 'HeaderCtrl'
},
'footer': {
templateUrl: 'home/footer.html'
}
},
data: {
requiresLogin: true
}
}).state('root.home', {
url: '/',
views: {
'#': {
templateUrl: 'home/home.html'
}
},
data: {
requiresLogin: true
}
})
$urlRouterProvider.otherwise('/');
authProvider.init({
domain: AUTH0_DOMAIN,
clientID: AUTH0_CLIENT_ID,
loginUrl: '/login'
});
jwtInterceptorProvider.tokenGetter = function(store) {
return store.get('token');
}
$httpProvider.interceptors.push('jwtInterceptor');
})
.run(function($rootScope, auth, store, jwtHelper, $location, $state, $stateParams) {
$rootScope.$on('$locationChangeStart', function() {
if (!auth.isAuthenticated) {
var token = store.get('token');
if (token) {
if (!jwtHelper.isTokenExpired(token)) {
auth.authenticate(store.get('profile'), token);
} else {
$location.path('/login');
}
}
}
});
})
.controller('AppCtrl', function AppCtrl($scope, $location) {
$scope.$on('$routeChangeSuccess', function(e, nextRoute) {
if (nextRoute.$$route && angular.isDefined(nextRoute.$$route.pageTitle)) {
$scope.pageTitle = nextRoute.$$route.pageTitle + ' | Auth0 Sample';
}
});
})
If I do login & the root that's commented out, everything works fine. But I need to put in a header and footer (the files are correct) and when I try the root + root.home, I get a blank screen with no errors on the browser's console either.
I'm trying to go off of a few examples from online (such as this one) but none are working out so I don't know what I'm doing wrong.
Right now my header/footer.html just say header/footer.html while home has a button on it.
Added the full app.js in case that helps. Each html (footer/header/home) just has
<h1>Home</h1>
<div ui-view></div>
Edit: index.html
<body>
<div ui-view="header"></div>
<div ui-view></div>
<div ui-view="footer"></div>
</body>
app.js
.state('root.home', {
url: '/',
views: {
'#': {
templateUrl: 'views/home.html',
controller: 'HomeCtrl'
}
},
data: {
requiresLogin: true
}
})
I believe your issue here is your route is looking for a view named container not a class.
<div ui-view="container"></div>
Since it can't find a view named that it does not insert anything in the view.
Or you can just change your view route to be:
views: {
'#': {
templateUrl: 'home/home.html'
}
Which will tell it to insert that HTML in the first unnamed view it finds.
You can find a break down of how nested views work with UI-Router here
Assuming your home.html looks like this:
<div ui-view="header"></div>
<div ui-view="footer"></div>
your route should be something like
views: {
'header#home': {
templateUrl: 'home/header.html',
controller: 'HeaderCtrl'
},
'footer#home': {
templateUrl: 'home/footer.html'
}
},
data: {
requiresLogin: true
}
I'm building a mobile app with ionic, I'm facing a strange problem ..
If I reload the page ( F5 ) from, let say "/tabs/connected/channel/edit" I'm always redirected to "/tabs/home" ( after the state resolving ).
PS : The resolve phase is correclty executed and I never reject it. And then on promise resolving I'm always redirected to /tabs/home.
Here is my config block :
.config(function($stateProvider, $urlRouterProvider) {
var userResolve = function(user, $q, $auth) {
if (!$auth.isAuthenticated()) {
return $q.resolve();
}
if (user.loaded) {
return $q.resolve();
}
return user.blockingRefresh();
};
// 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
// setup an abstract state for the tabs directive
.state('tabs', {
url: '/tabs',
abstract: true,
templateUrl: 'templates/tabs.html'
})
.state('tabs.home', {
url: '/home',
views: {
'home-tab': {
templateUrl: 'templates/home.html',
controller: ''
}
}
})
.state('tabs.account', {
url: '/account',
views: {
'account-tab': {
templateUrl: 'templates/account/account.html',
controller: 'AccountController'
}
},
resolve: {
userData: userResolve
}
})
.state('tabs.login', {
url: '/account/login',
views: {
'account-tab': {
templateUrl: 'templates/account/login.html',
controller: 'AccountController'
}
}
})
.state('tabs.register', {
url: '/account/register',
views: {
'account-tab': {
templateUrl: 'templates/account/register.html',
controller: 'RegisterController'
}
}
})
.state('tabs.connected', {
url: '/connected',
abstract: true,
views: {
'account-tab': {
templateUrl: "templates/connected.html"
}
},
resolve: {
userData: userResolve
}
})
.state('tabs.connected.channel-create', {
url: '/channel/create',
templateUrl: 'templates/channel/create.html',
controller: 'CreateChannelController'
})
.state('tabs.connected.channel-edit', {
url: '/channel/edit',
templateUrl: 'templates/channel/edit.html',
controller: 'EditChannelController'
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/tabs/account');
})
Here is tabs.html :
<ion-tabs class="tabs-assertive tabs-icon-top">
<ion-tab title="Home" ui-sref="tabs.home" icon-on="ion-ios-filing" icon-off="ion-ios-filing-outline">
<ion-nav-view name="home-tab"></ion-nav-view>
</ion-tab>
<ion-tab title="Account" ui-sref="tabs.account" icon-on="ion-ios-gear" icon-off="ion-ios-gear-outline">
<ion-nav-view name="account-tab"></ion-nav-view>
</ion-tab>
I must precise that I never use $state.go('/tabs/home') I'm my code at all. I'm sure of that.
My goal is to stay on the same route even if I reload the app. ( This problem does not occurs on some state and I don't know why because they doesn't do anything different than the problematic ones .. )
Thank you !
I also got this type of error in Angular Ui-Router.
Below solution is work for me.
Just change it too
.state('tabs.connected.channelcreate', {
url: '/channelcreate',
templateUrl: 'templates/channel/create.html',
controller: 'CreateChannelController'
})
url should be
"/tabs/connected/channeledit"
And it will work.
I have a go back button that when i hit the ng-click='goBack()'. i can see the url in the browser that changes from http://app:8888/#/main/payments to http://app:8888/#/main/products/7 which is the right path that I want to go back to but the problem is that the view doesn't transition there.
I have to hit refresh button in order to go there or do a window.location.reload after the $ionicHistory.goBack();.
I don't want to reload the whole page I want to transition that view to the previous one.
this is my html
<div class="row">
<div class="col col-25">
<button ng-click="goBack()" class="button button-large button-block button-royal">Go Back</button>
</div>
</div>
this is my controller
.controller('paymentsController', function($scope, $localStorage, $log, $state, $window, $ionicHistory){
$scope.goBack = function(){
$ionicHistory.goBack();
}
})
this is my app.js I don't know if this would help.
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ngStorage'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider){
//$ionicConfigProvider.views.transition('none');
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login',{
url: '/',
templateUrl: 'templates/login.html',
controller: 'loginController'
})
.state('main', {
url: '/main',
templateUrl: 'templates/main.html',
controller: 'mainController',
abstract: true
})
.state('main.categories', {
url: '/categories',
views: {
'categories': {
templateUrl: 'templates/categories.html',
controller: 'categoriesController'
}
}
})
.state('main.products', {
url: '/products/:productId',
views: {
'products': {
templateUrl: 'templates/products.html',
controller: 'productsController'
}
}
})
.state('main.payments', {
url: '/payments',
views: {
'payments': {
templateUrl: 'templates/payments.html',
controller: 'paymentsController'
}
}
})
})
Call this from your controller where you want to go back..
var backCount = 1;
$rootScope.$ionicGoBack();
$rootScope.$ionicGoBack = function(backCount) {
$ionicHistory.goBack(backCount);
};
Use $state to redirect to particular view:
$state.transitionTo('main');
here 'main' is your view name that you have defined into your urlrouterprovider.
OR
You can also use $location
$location.path('main');
don't forget to add $state or $location into your controller's parameter.
I am having issues with Ionic/Angular. I am new to ionic, and need some help. Most of the stuff online is for splash screens, so I came here for further assistance.
I want the app to default land on to the "welcome" page. What do I need to write? My code is as follows.
angular.module('starter', ['ionic', 'starter.controllers'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('app.welcome', {
url: "/welcome",
views: {
'menuContent': {
templateUrl: "templates/welcome.html"
}
}
})
.state('app.bulletin', {
url: "/bulletin",
views: {
'menuContent': {
templateUrl: "templates/bulletin.html"
}
}
})
.state('app.lunch', {
url: "/lunch",
views: {
'menuContent': {
templateUrl: "templates/lunch.html"
}
}
})
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise("/app/welcome");
});
I think you need to remove the }); above the $urlRouterProvider since you have to define the otherwise() inside of the config;
app.config(function($urlRouterProvider){
// if the path doesn't match any of the urls you configured
// otherwise will take care of routing the user to the specified url
$urlRouterProvider.otherwise('/index');
})