When a user attempts to visit my home page, I want to be able to redirect them to a different state based on query params.
For example, if URL is: http://example.com, then load the home page.
If URL is: http://example.com?channel=1, then don't load the home page and go to some other state right away.
Here's what I have (doesn't work):
$stateProvider
...
.state('default-template.home', {
url: '/?channel&campaign',
views: {
'': {
templateUrl: 'app/pages/home/home.html',
controller: 'HomeCtrl as vm'
}
},
resolve: {
data: ['$rootScope', '$stateParams', '$state', function($rootScope, $stateParams, $state) {
var channel = $stateParams.channel;
// If channel is 1, redirect
if (channel === 1) {
$state.go('default-template.other-state', {channel: channel});
}
}]
}
})
The problem seems to be that while both states get kicked off ($stateChangeStart event gets kicked off), the end result is the user always ends up on the home page.
Any thoughts on how to make this work?
You can use the $location built-in service to achieve this.
Your code must have an additional state for the fake path as below
$stateProvider
...
.state('default-template.fake.home', {
url: '/?channel',
views: {
'': {
templateUrl: 'app/pages/home/home.html',
controller: 'HomeCtrl as vm'
}
},
})
.state('default-template.home', {
url: '/?channel&campaign',
views: {
'': {
templateUrl: 'app/pages/home/home.html',
controller: 'HomeCtrl as vm'
}
},
resolve: {
data: ['$rootScope', '$stateParams', '$state', function($rootScope, $stateParams, $state) {
var channel = $stateParams.channel;
// If channel is 1, redirect
if (channel === 1) {
$state.go('default-template.other-state', {channel: channel});
}
}]
}
})
Your HomeCtrl should use the $location service to access the url as below
angular.controller('HomeCtrl',function($location,$state){
if($location.$$url= '') //check if it is empty
$state.go('default-template.home');
....................................
})
LIVE DEMO
Related
Hi all I having a hard time figuring this out and ran out of ideas. I have this website which I should restrict some urls if the user has no authentication. I reviewed some questions and found something similar to this. But it is not quite what I wanted it to be.
So I have some link which do not require user authentication but can access the url.
Other link which needs both, access and user authentication.
So this is my app.js looks
angular.module('efutures', [
'ngRoute',
'ngCookies',
'ui.bootstrap',
]).config(['$routeProvider', '$httpProvider', function ($routeProvider, $httpProvider) {
$routeProvider.when('/login', {
templateUrl: 'app/pages/login.html',
controller: 'LoginController',
access: {
allowAnonymous: true //no need auth
}
})
.when('/signup', {
templateUrl: 'app/pages/Signup.html',
controller: 'SignupController',
access: {
allowAnonymous: true //no need auth
}
})
.when('/enteremail', {
templateUrl: 'app/pages/reset pages/reenteremail.html',
controller: 'EmailController',
access: {
allowAnonymous: true //no need auth
}
})
.when('/password-reset', {
templateUrl: 'app/pages/reset pages/password.reset.html',
controller: 'ResetPwdController',
access: {
allowAnonymous: false //needs auth
}
})
.when('/dashboard', {
templateUrl: 'app/pages/dashboard.html',
controller: 'DashboardController',
access: {
allowAnonymous: false //needs auth
}
})
.when('/registration', {
templateUrl: 'app/pages/registration1.html',
controller: 'registationController'
access: {
allowAnonymous: false //needs auth
}
});
$routeProvider.otherwise({
redirectTo: '/login'
});
}]).run(run);
run.$inject = ['$rootScope', '$location', '$cookieStore', '$http'];
function run($rootScope, $location, $cookieStore, $http) {
$rootScope.hasauth = localStorage.getItem('hasauth');
$rootScope.username = localStorage.getItem('username');
$rootScope.$on('$routeChangeStart', function (event, next, current) {
//console.log($rootScope.hasauth);
//console.log(next.access.allowAnonymous);
if (next.access.allowAnonymous || $rootScope.hasauth === null) {
$location.path('/login');
}
else {
event.preventDefault();
}
});
}
So as above explains code, I have 3 pages which doesn't need authentication and can be allowed to access the urls. Also after Logged in I should restrict going back to those 3 pages but should access other remaining ones
the authentication is taken by the loacalStorage hasauth which returns true when logged in and null when not.
How do I approach this? Help is greatly appreciated.
I have been making an app in AngularJS with Angular-ui-router based on Ionic Framework. It works perfect on the desktop in every web browser, but it does not show anything on my mobile (after build I run it on 2 devices). The problem is that it doesn't load template inside ui-view.
I have got an index.html file, the body section is below (in head section there is everything included):
<body ng-app="starter">
<div ui-view=""></div>
</body>
And the part of app.js - run and config.
angular.module('starter', ['ionic', 'ngStorage', 'ngAnimate', 'naif.base64', 'ui.router'])
.run(function($ionicPlatform, $rootScope, $location) {
$ionicPlatform.ready(function() {
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
});
history = [];
$rootScope.$on('$routeChangeSuccess', function() {
history.push($location.$$path);
});
$rootScope.back = function () {
history.back();
};
})
.config(function($stateProvider, $urlRouterProvider) {
"use strict";
$stateProvider
.state('connectionCheck', {
url: '/',
controller: ['$scope', '$location', '$http',
function($scope, $location, $http) {
$http.get('http://pingurl.com')
.success(function(data) {
jdata = data;
if (data.status === "success") {
$location.path('/login');
}else{
$location.path('/error');
}
})
.error(function() {
$location.path('/error');
});
$scope.retry = function() {
$location.path('/');
};
}
]
})
.state('login', {
url: '/login',
templateUrl: 'login.html'
})
.state('main', {
url: '/main',
templateUrl: 'main.html',
controller: ['$scope', '$location', '$localStorage',
function($scope, $location, $localStorage) {
$scope.username = $localStorage.username;
$scope.token = $localStorage.token;
$scope.email = $localStorage.email;
$scope.goToAlerts = function() {
$location.path('/alerts');
};
$scope.goToSettings = function() {
$location.path('/settings');
};
$scope.goToLocation = function() {
$location.path('/location');
};
$scope.goToSymptoms = function() {
$location.path('/symptoms');
};
$scope.getClass = function(path) {
if ($location.path().substr(0, path.length) == path) {
return "active"
} else {
return ""
}
};
}
]
})
.state('error', {
url: '/error',
templateUrl: 'error.html'
})
.state('register', {
url: '/register',
templateUrl: 'register.html',
})
.state('push', {
url: '/push',
templateUrl: 'push.html',
})
.state('alerts', {
url: '/alerts',
templateUrl: 'alerts.html'
})
.state('newSymptom', {
url: '/newSymptom',
templateUrl: 'newsymptom.html'
})
.state('symptoms', {
url: '/symptoms',
templateUrl: 'symptoms.html'
})
.state('newAlert', {
url: '/newalert',
templateUrl: 'newalert.html'
})
.state('settings', {
url: '/settings',
templateUrl: 'settings.html'
})
.state('location', {
url: '/location',
templateUrl: 'location.html'
});
$urlRouterProvider.otherwise('/');
}).
//some controllers goes here
What I have already checked/tried to do?
I put example content to index.html - it worked.
I tried chanage the name of ui-view and add them in templateURL values of each state.
I changed the .html files to exlude error in them, but it did not helped.
Can anyone more experienced with Ionic/Angular give me a hint what is wrong here?
I seem to notice that it's often due to the modules you're loading in. So It's likely in this line.
angular.module('starter', ['ionic', 'ngStorage', 'ngAnimate', 'naif.base64', 'ui.router'])
Try checking each module by making sure:
You added it to your index.html
it's being called correctly
it's up to date
You can figure out by removing each, one at a time and then seeing if it works on the device.
Also know that AngularJS out of the box uses AngularUI Router and this uses a thing called routing for views. The UI-Router uses a thing called states that is the most used but the unofficial way for AngularJS and Ionic uses their own view state system that is basically the same thing as the UI-Router just with the Ionic namespace. So that is something you need to look up or you may find yourself running into a lot of walls during you builds because you are calling ui.router and I bet it's what's confusing your app, so remove it.
Using angular ui-router I'm trying to use $state.go() to change to the blogEdit state after creating a new entry with blogCreate to continue editing after saving. When I click to save and trigger addPost() method, it doesnt redirect correctly and I see /#/null as the route in the address bar instead of the expected /blog/post/:postId/edit.
blogModule.controller('PostCreateController', ['$scope', '$state', '$stateParams', 'PostResource',
function ($scope, $state, $stateParams, PostResource) {
$scope.post = new PostResource();
$scope.addPost = function () {
$scope.post.$save(function () {
$state.go('blogEdit', {postId: $stateParams.postId}); // THIS SHOULD REDIRECT TO CONTINUE EDITING POST
});
}
}
]);
blogModule.controller('PostEditController', ['$scope', '$stateParams', 'PostResource',
function ($scope, $stateParams, PostResource) {
$scope.post = PostResource.get({postId: $stateParams.postId});
$scope.updatePost = function () {
$scope.post.$update({postId: $stateParams.postId});
}
}
]);
State route configuration:
var app = angular.module('app', [
'ui.router',
'blogModule'
]);
app.config(['$stateProvider', function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('blog', {
url: '/blog',
templateUrl: 'app/blog/view/blog-list.html',
controller: 'PostListController'
})
.state('blogView', {
url: '/blog/post/{postId:[0-9]}',
templateUrl: 'app/blog/view/blog-detail.html',
controller: 'PostViewController'
})
.state('blogCreate', {
url: '/blog/post/new',
templateUrl: 'app/blog/view/blog-create.html',
controller: 'PostCreateController'
})
.state('blogEdit', {
url: '/blog/post/{postId:[0-9]}/edit',
templateUrl: 'app/blog/view/blog-edit.html',
controller: 'PostEditController'
});
}]);
It seems to do this regardless of what state I try to change to.
I suppose you are saving your post on backend. When you perform save (PUT) operation your backend should return you some response. The response should be like HTTP 201 Entity created and there should be location attribute set (f.e. http://example.com/blog/post/1). Then you can get the id from location header like this:
$scope.post.$save(function (createdPost, headers) {
var postId = headers.location.split("/").pop();
$state.go('blogEdit', {postId: postId});
});
Another way is to just ignore headers and return json response from your backend. F.e. {"postId": 1, "title": "New post", ...}. Then you can do something like:
$scope.post.$save(function (createdPost) {
$state.go('blogEdit', {postId: createdPost.postId});
});
The most important is to know API of your backend (what "it returns").
I am having weird issue probably caching issue while navigating from grand-child(/dashboard/1/production) to parent(/dashboard).
Following are few screenshots:
The selections i.e Delphi-UI and production shouldn't persists.
Following is my snippet of application config:
$stateProvider
.state('root', {
url: '/',
views: {
'header': {
templateUrl: 'ngapp/templates/header.html'
}
}
})
// dashboard routes
.state('root.dashboard', {
url: 'dashboard',
views: {
'content#' : {
templateUrl: 'ngapp/home/templates/dashboard.html',
controller: 'DashboardCtrl',
controllerAs: 'vm'
}
}
})
.state('root.dashboard.app', {
url: '/{id:int}',
views: {
'body#root.dashboard' : {
templateUrl: 'ngapp/home/templates/dashboard-body.html',
controller: 'DashboardBodyCtrl'
}
}
})
.state('root.dashboard.app.env', {
url: '/:name',
views: {
'body#root.dashboard' : {
templateUrl: 'ngapp/home/templates/env-content.html',
controller: 'EnvContentCtrl'
}
}
});
And DashboardCtrl is:
controllers.controller('DashboardCtrl', ['$scope', '$http', '$state', '$timeout', 'appsFactory', function($scope, $http, $state, $timeout, appsFactory) {
$scope.envs = [];
$scope.deps = [];
$scope.envBtnText = $scope.appBtnText = "Choose here";
$scope.headerTitle = "Environment Configuration And Management";
$scope.appStatus = {
isopen: false
};
$scope.envStatus = {
isopen: false
};
appsFactory.list(function(data) {
$scope.apps = data;
});
}]);
Full controller code : http://goo.gl/BWtiU5
Project hosted here : https://github.com/budhrg/atlantis-dashboard
Also, navigating back to Atlantis UI(dashboard) doesn't reset data like
$scope.envs, $scope.deps, $scope.envBtnText and $scope.appBtnText.
What might be issue here? Am I missing anything?
Nested States & Views
When the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well. Below, when the "contacts.list" state is active, the "contacts" state is implicitly active as well, because it's the parent state to "contacts.list".
Your controller isn't getting re-instantiated (expected). There are a couple ways to handle this.
See:
How to make angular ui-router's parent state always execute controller code when state changes?
I'm trying to implement login using Angular.js with Laravel as a back end. I'm using an abstract state for handling the layout. There are 2 abstract states: 1 for public pages and 1 for admin pages. The problem is when I login, when I use $state.go('admin.dash') or $window.location.href = '#/admin/dash' it redirects me to the page but the sidebar isn't loaded. It only loads when I access the page directly or do a full page refresh on the browser.
Here's what my loginController looks like:
(function(){
angular.module('starter.controllers')
.controller('LoginController', ['$scope', 'UserService', '$state', '$window', LoginController]);
function LoginController($scope, UserService, $state, $window){
var me = this;
me.loginUser = function(user){
UserService.login(user).then(function(data){
$window.location.href = ('#/admin/dash'); //also tried $state.go
});
};
};
})();
And here's what the app configuration for the states look like:
.config(function($stateProvider, $urlRouterProvider) {
.state('home', {
url: "/home",
abstract: true,
templateUrl: "templates/layouts/tabs.html"
})
.state('home.login', {
url: '/login',
views: {
'home-login': {
templateUrl: 'templates/tab-login.html',
controller: 'LoginController'
}
}
})
.state('admin', {
url: "/admin",
abstract: true,
templateUrl: "templates/layouts/admin-menu.html"
})
.state('admin.dash', {
url: '/dash',
views: {
'menuContent': {
templateUrl: 'templates/admin/dash.html'
}
}
});
So basically I'm trying to redirect from the home state to the admin state. When I checked on chrome dev tools the HTML is actually loaded, but I don't know why the sidebar just wont show up:
Here's a screenshot when I use $state.go or $window.location.href:
And here's how it looks like when I access it directly: