I am trying to set up angular routing. When I navigate to a route using <a ui-sref="classification.sequences.index"> it gets routed to the correct location,changes the url to http://localhost/classification/sequences/index and outputs enter 0, enter 5, enter 2 in the console.
But if I manually refresh the page or navigate to this url from scratch no routing happens and nothing is outputted to the console. But if I click the link button it will then route properly.
Is there something you have to set so angular will attempt to route on load or have I made a silly mistake somewhere?
My code can be seen below-
policyManagerApp.config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
function($stateProvider, $urlRouterProvider, $locationProvider) {
// Activates HTML5 History API for modern browsers and sets the hashbang
// for legacy browsers
$locationProvider.html5Mode(true).hashPrefix('!');
$urlRouterProvider.when("", "/classification/index");
$urlRouterProvider.when("/", "/classification/index");
// For any unmatched url, send to /classification/index
$urlRouterProvider.otherwise("/classification/index");
$stateProvider
.state('classification', {
url: '/classification',
abstract: true,
template: '<ui-view/>',
onEnter: function () {
console.log("enter 0");
}
})
.state('classification.index', {
url: '/index',
templateUrl: '/html/partials/classification/index.html',
controller: 'PolicyManagerCtrl',
data: {
ncyBreadcrumbLabel: 'Classification'
},
onEnter: function () {
console.log("enter 1");
}
})
.state('classification.sequences', {
url: '/sequences',
abstract: true,
template: '<ui-view/>',
onEnter: function () {
console.log("enter 5");
}
})
.state('classification.sequences.index', {
url: '/index',
templateUrl: '/html/partials/classification/sequences/index.html',
data: {
ncyBreadcrumbLabel: 'Collection Sequences'
},
onEnter: function () {
console.log("enter 2");
}
})
.state('classification.sequences.detail', {
url: '/:id',
templateUrl: '/html/partials/classification/sequences/detail.html',
controller: 'SequenceDetailCtrl',
data: {
ncyBreadcrumbParent: 'classification.sequences.index',
ncyBreadcrumbLabel: '{{sequence.name}}'
},
onEnter: function () {
console.log("enter 3");
}
})
;
}
]);
It turns out I wasn't calling policyManagerApp.run() after the config line so it was never evaluating against the starting url.
Related
I am trying to make states and load views with UI router, except it keeps redirecting me to index. I am not able to figure out what is happening.
I have declared the app.js somewhere else, I am just posting the router.js here.
Code
angular.module("MyApp").config(function($stateProvider) {
$stateProvider
.state('clinicdashboard', {
url: '/clinicdashboards',
templateUrl: 'clinicdashboard/views/index.html',
controller: 'clinicDashboardCtrl',
resolve: {
loginRequired: loginRequired,
patientlist: ['$http', function($http) {
console.log("hello");
return $http({
method: 'GET',
url: 'users/api/getPatientList'
});
}]
}
})
.state('patientList', {
url: '/patientlist/:id',
templateUrl: 'clinicdashboard/views/detail.html',
controller: 'clinicDashboardCtrlDetail',
resolve: {
loginRequired: loginRequired
}
})
.state('clinicProfile', {
url: '/clinicProfile',
templateUrl: 'clinicdashboard/views/clinicProfile.html',
// controller: 'clinicDashboardCtrlDetail',
resolve: {
loginRequired: loginRequired
}
})
.state('clinicProfile.clinicProfileEdit', {
url: '/clinicProfileEdit',
templateUrl: 'clinicdashboard/views/clinicProfileEdit.html',
// controller: 'clinicDashboardCtrlDetail',
resolve: {
loginRequired: loginRequired
}
})
function loginRequired($q, $location, $auth) {
var deferred = $q.defer();
if ($auth.isAuthenticated()) {
deferred.resolve();
} else {
$location.path('/login');
}
return deferred.promise;
}
})
I have put all the files in their correct directory.
It is showing no error on the console or nodemon or anywhere.
Its simply just redirecting me to localhost, even if I try to go to something like localhost/clinicProfile
Can you try in your config,
yourapp.config(
function( $stateProvider,
$locationProvider) {
$locationProvider.html5Mode(false);
})
By default it is false, so you can remove this settings if you have specified and try.
I just suspected this because in your url (localhost/clinicProfile) , there is no "#". Have you tried localhost/#/clinicProfile as well?
Also, please try enabling HTML5Mode and and include this line in the head of index.html: OR try $locationProvider.html5Mode({ enabled: true, requireBase: false }); So $locationProvider wont be dependent on base tag.
Hi I 'm developing an app with IONIC Framework and am developing the user validation and error have not let me go , I leave some details of logic I'm using:
app.js:
angular.module('skulApp', ['ionic', 'ionic-material', 'ionMdInput', 'ngCordova'])
.run(function($ionicPlatform, $rootScope, $state, AUTH_EVENTS, _Auth_Service, sqliteService){
$ionicPlatform.ready(function(){
if (window.cordova && window.cordova.plugins.Keyboard)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
if (window.StatusBar)
StatusBar.styleDefault();
sqliteService.preloadDataBase(true);
});
$rootScope.$on('$stateChangeStart', function(event, next, nextParams, fromState) {
if ('data' in next && 'authorizedRoles' in next.data) {
var authorizedRoles = next.data.authorizedRoles;
if (!_Auth_Service.isAuthorized(authorizedRoles)) {
event.preventDefault();
$state.go($state.current, nextParams, {reload: true});
$rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
}
}
if (!_Auth_Service.isAuthenticated()) {
if (next.name !== 'login') {
event.preventDefault();
$state.go('login');
}
}
});
})
app.config.js:
.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider, USER_ROLES) {
$stateProvider
.state('main', {
url: '/',
abstract: true,
templateUrl: 'templates/main.html'
})
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginCtrl'
})
.state('main.dashboard', {
url: 'main/dashboard',
views: {
'menuContent': {
templateUrl: 'templates/dashboard.html',
controller: 'DashboardCtrl'
},
'fabContent': {
template: '<button id="fab-profile" class="button button-fab button-fab-bottom-right button-energized-900" ui-sref="main.edit"><i class="icon ion-edit"></i></button>',
controller: function($timeout) {
$timeout(function() {
document.getElementById('fab-profile').classList.toggle('on');
}, 800);
}
}
},
data: {
authorizedRoles: [
USER_ROLES.admin,
USER_ROLES.teacher,
USER_ROLES.father
]
}
})
.state('main.edit', {
url: 'main/edit',
views: {
'menuContent': {
templateUrl: 'templates/edit.html',
controller: 'EditCtrl'
},
'fabContent': {
template: ''
}
}
});
$urlRouterProvider.otherwise(function($injector, $location){
var $state = $injector.get("$state");
$state.go('main.dashboard');
});
});
The error is:
Error: Cannot transition to abstract state '[object Object]'
at Object.transitionTo (ionic.bundle.js:40332)
at Object.go (ionic.bundle.js:40262)
at app.js:52
at Scope.$broadcast (ionic.bundle.js:23003)
at Object.transitionTo (ionic.bundle.js:40395)
at Object.go (ionic.bundle.js:40262)
at app.config.js:210
at check (ionic.bundle.js:39247)
at update (ionic.bundle.js:39259)
at Scope.$broadcast (ionic.bundle.js:23003)
Te line in app.js is that:
$state.go($state.current, nextParams, {reload: true});
Here I do not include services , constants, controls , policies, and others, if they consider it necessary I do know and update the question. Please i don't do! Help me
I think your problem is due to your $stateChangeStart method.
In case it enters the first couple of if conditions, this line:
$state.go($state.current, nextParams, {reload: true});
Will abourt your try to go to /main/dashboard, and the state will remain in /.
Well if you open your broswer on '/' the only matching state is your abstract one. Since it's matching otherwise doesn't get executed.
Use this instead of otherwise to redirect to your dashboard.
$urlRouterProvider.when('/', '/main/dashboard');
is it possible to create a nested views in ui router with conditions?
The conditions is assigned to the user roles.
For example I have two types of users: admin and user.
If user is opening the setting page then ui router is adding only this view which is assign to his role.
Here is example of my config code
var app = angular.module('myApp', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider){
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'homeController'
})
.state('settings', {
url: '/settings',
data: {
roles: ['admin', 'moderator', 'user']
},
views:{
'':{
templateUrl:'/settings.html',
},
'piView#settings':{
data: {
roles: ['user']
},
templateUrl:'/personalInformation.html'
},
'permissionsView#settings':{//load this view if user is administrator
//I need some condition for this
data: {
roles: ['admin']
},
templateUrl: '/permissionsView.html'
}
},
controller: 'settingsController'
});
$urlRouterProvider.otherwise( function($injector) {
var $state = $injector.get("$state");
$state.go('/home');
});
});
The view will be injected for each user (admin or anonymous). But we can manage which view. The best vay would be to use templateProvider.
Based on this Q & A:
Confusing $locationChangeSuccess and $stateChangeStart
I used the plunker from above source and adjusted it a bit
So, let's have these two targets (inside of index.html)
<div ui-view="onlyForAdmin"></div>
<div ui-view=""></div>
And a state public, which for Admin will reveal even content of the onlyForAdmin, with settings like this:
.state('public', {
url: "/public",
data: { isPublic: true },
views: {
'#' : {
templateUrl: 'tpl.html',
data: { isPublic: true },
},
'onlyForAdmin#' : {
templateProvider: ['$templateRequest','userService',
function($templateRequest,userService)
{
if(userService.isAdmin())
{
return $templateRequest("justForAdmin.html");
}
return ""; // other than admin will see nothing
}
]
}
}
})
the content of the justForAdmin.html (e.g. <h2>just for admin</h2>) will be injected only of some authorization service will find user as admin...
Check it here
I have simple angular ui router app:
.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('');
$stateProvider
.state('welcome', {
url: '/',
templateUrl: 'components/welcome/welcome.html',
controller: 'MainController',
data: {
auth: true
}
})
.state('courses', {
url: '/courses',
templateUrl: 'components/courses/courses.html',
controller: 'MainController',
data: {
auth: true
}
})
.state('login', {
url: '/login',
templateUrl: 'components/login/login.html',
controller: 'LoginController',
data: {
auth: false
}
})
})
And when user first time go to browser execute this code:
.run(['$rootScope','$http', '$state', 'UserService','userEmailGetService','isUserLoggedService',
function ( $rootScope,$http, $state, UserService,userEmailGetService,isUserLoggedService) {
UserService.CheckIfLogged()
.success(function(data) {
userEmailGetService.setUserEmail(data.email);
isUserLoggedService.setIsLogged(true);
stateCallback();
})
.error(function(data) {
//console.log(data);
isUserLoggedService.setIsLogged(false);
stateCallback();
$state.go("login");
});
this.stateCallback = function() {
$rootScope.$on("$stateChangeStart", function (event, toState, toParams, fromState) {
alert("Hello");
if (toState.data.auth == true && !isUserLoggedService.getIsLogged()) {
event.preventDefault();
$state.go("login");
}
if (toState.data.auth == false && isUserLoggedService.getIsLogged()) {
event.preventDefault();
$state.go("welcome");
}
});
};
}])
Routing in Firefox works ok but in Chrome when I logged and I go to login section, browser should ban this redirect and go to welcome section, when I run programmer console in chrome and I redirect to login panel when I logged evrythink works correct, very strange for me. When I added alert in stateChangeStart firefox show me this alert, chrome not, only when I open programmer panel.
You have a race condition as this is async:
UserService.CheckIfLogged()
.success(function(data) {
userEmailGetService.setUserEmail(data.email);
isUserLoggedService.setIsLogged(true);
stateCallback();
})
.error(function(data) {
//console.log(data);
isUserLoggedService.setIsLogged(false);
stateCallback();
$state.go("login");
});
This means that if the router is run before the validation code finishes, it will go to the login route instead of the welcome.
The solution is to use the resolve property of the routing, as it accepts promises, and will wait for the async response.
stateCallback is not defined because you assigned this function to this. Remove this from declaration this.stateCallback and then this code should work.
I 'm creating a mobile application based on angularjs . To load a list , I'm making a call to an API Rest. I am using a resource for doing this. When I 'm connected to the wifi it works perfectly , but when I use ยท g, the recuerso not call the API and always returns the previous value.
How I can refresh the application each time you call?
SERVICES.JS
.factory('Exercises', function($resource) {
// localhost: Local
// 79.148.230.240: server
return $resource('http://79.148.230.240:3000/wodapp/users/:idUser/exercises/:idExercise', {
idUser: '55357c898aa778b657adafb4',
idExercise: '#_id'
}, {
update: {
method: 'PUT'
}
});
});
CONTROLLERS
.controller('ExerciseController', function($q, $scope, $state, Exercises) {
// reload exercises every time when we enter in the controller
Exercises.query(function(data) {
$scope.exercises = data;
});
// refresh the list of exercises
$scope.doRefresh = function() {
// reload exercises
Exercises.query().$promise.then(function(data) {
$scope.exercises = data;
}, function(error) {
console.log('error');
});
// control refresh element
$scope.$broadcast('scroll.refreshComplete');
$scope.$apply();
}
// create a new execersie template
$scope.newExercise = function() {
$state.go('newExercise');
};
// delete a exercise
$scope.deleteExercise = function(i) {
// we access to the element using index param
var exerciseDelete = $scope.exercises[i];
// delete exercise calling Rest API and later remove to the scope
exerciseDelete.$delete(function() {
$scope.exercises.splice(i, 1);
});
};
})
APP.js
angular.module('wodapp', ['ionic', 'ngResource', 'wodapp.controllers','wodapp.services'])
// Run
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// ionic is loaded
});
})
// Config
.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$stateProvider
.state('slide', {
url: '/',
templateUrl: 'templates/slides.html',
controller: 'SlideController'
})
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginController'
})
.state('dashboard', {
url: '/dashboard',
templateUrl: 'templates/dashboard.html',
controller: 'DashboardController'
})
.state('exercise', {
url: '/exercise',
templateUrl: 'templates/exercises.html',
controller: 'ExerciseController'
})
.state('newExercise',{
url: '/newExercise',
templateUrl: 'templates/newExercise.html',
controller: 'NewExerciseController'
});
$urlRouterProvider.otherwise('/');
});
Inject $ionicView and then:
$ioniView.enter(function(){
Exercises.query(function(data) {
$scope.exercises = data;
});
})