My state configuration goes something like this:
.config(function ($stateProvider, $urlRouterProvider, $authProvider) {
$authProvider.facebook({
clientId: '16250xxxxxx',
scope: 'user_friends'
});
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('core', {
abstract: true,
template: '<ui-view>',
resolve: {
'authStatus' : function($auth, $q, User) {
var defer = $q.defer();
$auth.authenticate('facebook').then(function(result) {
User.update(result.data.user);
defer.resolve();
});
return defer.promise;
}
}
})
.state('home', {
parent: 'core',
url: '/home',
templateUrl: 'app/home/home.html'
})
....
.... other states
When my application loads, it enters the resolve block of 'core' state twice.
This causes the facebook authentication window to open twice..
Any clue why it would execute the core state twice ?
Found the reason for this occurence.
The satellizer $auth service would redirect to a default url upon resolving the authentication.
I simply had to reset that to '/home' in the config section of angular app
$authProvider.loginRedirect = '/home';
Related
What am I missing? Why would the Home template NOT load via .otherwise('/')? If I link to href="/#/" or ui-sref="home" everything works fine. However the Home template does NOT load if I try $urlRouterProvider.otherwise is working. The console does not show any errors.
Another interesting point is the URL is never modified when the first page loads. My other apps usually redirect from http://www.domain.com to http://www.domain.com/#/. This app is not showing the updated URL.
I have tried this in multiple browsers. No extensions or plugins are active.
Here are my routes:
(function () {
'use strict';
angular
.module('myapp')
.config(configRoutes);
configRoutes.$inject = ['$stateProvider', '$urlRouterProvider'];
function configRoutes ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/partials/home.html'
})
.state('login', {
url: '/login',
templateUrl: 'app/partials/login.html',
})
.state('signup', {
url: '/signup',
templateUrl: 'app/partials/signup.html',
})
.state('logout', {
url: '/logout',
template: null,
controller: 'LogoutCtrl'
})
.state('profile', {
url: '/profile',
templateUrl: 'app/partials/profile.html',
});
}
})();
I'm experiencing a weird issue with $urlRouterProvider.
In theory I should be able to see the 'here' message log every time the url changes, but I can only see that when the url typed is not in the 'state' list.
Can you telle me what's wrong with this code and why $urlRouterProvider.rule is not executed every url change?
This is my code for the stateProviderConfig:
angular.module('stateProviderConfig', [])
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise( function($injector) {
var $state = $injector.get('$state');
$state.go('app.dashboard');
});
$urlRouterProvider.rule(function ($injector, $location) {
console.log('here');
});
$stateProvider
.state('app', {
abstract: true,
url: '/app',
templateUrl: 'views/tmpl/app.html',
})
.state('app.404', {
url: '/404',
controller: 'Err404Controller',
templateUrl: 'views/tmpl/404.html'
...
...
}]);
This my main module definition:
$rootScope.$on('unauthorized', function () {
$state.go('login');
});
.config(
function ($stateProvider, $logProvider, $httpProvider) {
$logProvider.debugEnabled(true);
// main application area //
$stateProvider
.state('body', {
url: '/',
template: '<div ui-view />'
});
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'login.html',
controller: 'LoginController',
});
$httpProvider.interceptors.push('APIInterceptor');
});
Interceptor definition:
service('APIInterceptor', function($rootScope) {
// Just for testing
$rootScope.$broadcast('unauthorized');
}
It's not following this:
$state.go('login'); and seems like it's looping until Chrome fails the page. Without $state.go('login'); code runs ok but I need to open the login page on unauthorized. My question is how do I navigate to login state?
Thanks
Try this
$rootScope.$on('unauthorized', function ($state) {
$state.go('login');
});
I'm trying to redirect after login to a specific page in Meteor using AngularJS. But somehow it is not working. After login Meteor.user() is returning null. Because of this every time it is routing to messages page only. I have seen this example from one of the forums and developed on top of that.
angular.module("jaarvis").run(["$rootScope", "$state", "$meteor", function($rootScope, $state, $meteor) {
$meteor.autorun($rootScope, function(){
if (! Meteor.user()) {
console.log('user');
if (Meteor.loggingIn()) {
console.log('loggingIn ' + Meteor.user()); -- returning null
if(Meteor.user()) {
$state.go('onlineusers');
} else {
//On login
$state.go("messages");
}
}
else{
console.log('login');
$state.go('login');
}
}
});
}]);
Routes declared as below.
angular.module('jaarvis').config(['$urlRouterProvider', '$stateProvider', '$locationProvider',
function($urlRouterProvider, $stateProvider, $locationProvider){
$locationProvider.html5Mode(true);
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'login.ng.html',
controller: 'LoginCtrl'
})
.state('onlineusers',{
url: '/onlineusers',
templateUrl: 'client/onlineusers/onlineusers.ng.html',
controller: 'OnlineUsersCtrl'
})
.state('messages', {
url: '/messages',
templateUrl: 'client/chats.ng.html',
controller: 'ChatCtrl'
})
});
$urlRouterProvider.otherwise("/messages");
}]);
Logging using below snippet of code.
<meteor-include src="loginButtons"></meteor-include>
Michael is probably right about the root cause of the problem, but I think that a better alternative is provided by the the authentication methods of Angular-Meteor.
What you are going to want to do is to force the resolution of a promise on the route. From the Angular-Meteor docs (i.e. a general example...):
// In route config ('ui-router' in the example, but works with 'ngRoute' the same way)
$stateProvider
.state('home', {
url: '/',
templateUrl: 'client/views/home.ng.html',
controller: 'HomeController'
resolve: {
"currentUser": ["$meteor", function($meteor){
return $meteor.waitForUser();
}]
}
});
Your specific code would look something like:
angular.module('jaarvis').config(['$urlRouterProvider', '$stateProvider', '$locationProvider',
function($urlRouterProvider, $stateProvider, $locationProvider){
$locationProvider.html5Mode(true);
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'login.ng.html',
controller: 'LoginCtrl'
})
.state('onlineusers',{
url: '/onlineusers',
templateUrl: 'client/onlineusers/onlineusers.ng.html',
controller: 'OnlineUsersCtrl',
resolve: {
"currentUser": ["$meteor", function($meteor){
return $meteor.waitForUser();
}]
}
})
.state('messages', {
url: '/messages',
templateUrl: 'client/chats.ng.html',
controller: 'ChatCtrl',
resolve: {
"currentUser": ["$meteor", function($meteor){
return $meteor.waitForUser();
}]
}
})
});
$urlRouterProvider.otherwise("/messages");
}]);
And then on your ChatCtrl and OnlineUsersCtrl controllers, you would add currentUser as one of the variables to inject, like:
angular.module("rootModule").controller("ChatCtrl", ["$scope", "$meteor", ...,
function($scope, $meteor, ..., "currentUser"){
console.log(currentUser) // SHOULD PRINT WHAT YOU WANT
}
]);
You might also want to consider the $meteor.requireUser() promise as well, and then send the user back to the login page if the promise gets rejected. All of this is documented very well on the angular-meteor website.
Good luck!
It could be that the user object hasn't loaded yet. You can try:
if ( Meteor.userId() ) ...
instead
This one is baffling; I'm trying to use the simple $state.go() function in my app which uses ui-router, but I get this:
Uncaught Error: [$injector:modulerr] Failed to instantiate module MainApp due to:
Error: [$injector:modulerr] Failed to instantiate module GroupApp due to:
Error: [$injector:unpr] Unknown provider: $state
http://errors.angularjs.org/1.4.3/$injector/unpr?p0=%24state
at REGEX_STRING_REGEXP
Here is the code I am using:
var app = angular.module('GroupApp', ['ui.router']);
groupjs_config.$inject = ['$stateProvider', '$state', '$urlRouterProvider'];
app.config(groupjs_config);
groupjs_controller.$inject = ['$scope'];
app.controller('groupjs.ctrl', groupjs_controller);
//----------------------------------------------------
// FUNCTIONS
//----------------------------------------------------
function groupjs_config($stateProvider, $state, $urlRouterProvider){
// For any unmatched url, redirect to /state1
$stateProvider
.state('group', {
abstract: true,
url: "/group/:groupid",
onEnter: function(){
if (true){ //logged in
$state.go('group.home');
}
else {
$state.go('group.noaccess');
}
}
})
.state('group.home', {
url: "/group/:groupid",
templateUrl: "groups/group/group.html"
})
.state('group.noaccess', {
url: "/group/:groupid",
templateUrl: "groups/group/group_noaccess.html"
});
}
function groupjs_controller($scope){
$scope.hi = "hi";
$.material.checkbox('mycheckbox');
$scope.groups = [
];
}
Try injecting the $state to the onEnter method :
onEnter: ['$state',function($state){
if (true){ //logged in
$state.go('group.home');
}
else {
$state.go('group.noaccess');
}
}]
and take it out from the config:
groupjs_config.$inject = ['$stateProvider', '$urlRouterProvider'];
...
function groupjs_config($stateProvider, $urlRouterProvider){
Only providers and constants can be injected into config blocks see the table at the bottom of https://docs.angularjs.org/guide/providers
The $state can be injected into the controller, or any filter, factory, service, run block etc. but just not in config. In order for anything but a provider to be created it must first have been configured (this is what the config blocks are for, configuring providers of services/factories/values).
First change this line:
groupjs_config.$inject = ['$stateProvider', '$state', '$urlRouterProvider'];
to:
groupjs_config.$inject = ['$stateProvider', '$urlRouterProvider'];
Change your routing function like this:
function groupjs_config($stateProvider, $urlRouterProvider){
// For any unmatched url, redirect to /state1
$stateProvider
.state('group', {
abstract: true,
url: "/group/:groupid",
onEnter: ['$state',function($state){
if (true){ //logged in
$state.go('group.home');
}
else {
$state.go('group.noaccess');
}
}]
})
.state('group.home', {
url: "/group/:groupid",
templateUrl: "groups/group/group.html"
})
.state('group.noaccess', {
url: "/group/:groupid",
templateUrl: "groups/group/group_noaccess.html"
});
}
ui-router
$stateProvider
.state('admin', {
abstract: true,
url: '/admin',
template: '<div ui-view></div>'
})
.state('admin.index', {
url: '/index',
template: '<h3>Admin index</h3>'
})
.state('admin.users', {
url: '/users',
template: '<ul>...</ul>'
});
onEnter, onExit
Our app calls these callbacks when we transition into or out of a view. For both options, we can set a function we want called; these functions have access to the resolved data.
These callbacks give us the ability to trigger an action on a new view or before we head out to another state. It’s a good way to launch an “Are you sure?” modal view or request the user log in before they head into this state.