I am trying to capture a route to be something like
www.mysite.com/#name=ted&location=ca
I am using stateprovider and I setup as follow:
$stateProvider
.state('home', {
url: '/#name',
controller: function () {
alert('here')
do stuff...
}
})
but for some reason, alert never trigger.
Can someone help me about it? Thanks a lot!
To get params via query string you can use try:
$stateProvider
.state('home', {
url: '/?name&location',
controller: function () {
alert('here')
do stuff...
}
})
# will be there if HTML5 mode is disabled.
var app= angular.module('appName', []);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/home', {
templateUrl: 'templates/home.html',
controller: 'AddOrderController'
}).
when('/contact', {
templateUrl: 'templates/contact.html',
controller: 'ShowOrdersController'
}).
otherwise({
redirectTo: '/home'
});
}]);
Try This Is Example Of Navigation Using With route Providers .
When using ui.router, all routes need a template, include that in your state, remove the # sign from the URL and it should work
Related
I have a problem with migrating from ngroute to ui.router:
using ngroute i have couple angular files:
module.js
angular.module('betTogether', ['ngRoute']);
route.js
angular.module('betTogether').config(['$routeProvider',
function (
$routeProvider
) {
$routeProvider.
when('/descriptionBets', {
templateUrl: 'descriptionBets',
controller: 'descriptionBetsCtrl'
}).
when('/normalBets', {
templateUrl: 'normal',
controller: 'normalBetsCtrl'
}).
when('/addBet', {
templateUrl: 'addBet',
controller: 'addBetCtrl'
}).
otherwise({
redirectTo: '/descriptionBets'
});
}]);
normalBets.js
angular.module('betTogether').controller('normalBetsCtrl', [
'$scope','$http',
function($scope,$http){
$scope.typeBetsImages = [{link: "images/basketball.png", title:"basketball"},
{link: "images/tenis.png", title: "tenis"},
{link: "images/volleyball.png", title: "volleyball"},
{link: "images/football.png", title:"football"}
];
$http.get("/normalBets").success(function(data){
$scope.normalBets = data;
});
}]);
...and rest of controllers. And everything works ok.
Now i want to migrate to ui-router. so i change module.js and route.js like that:
module.js
angular.module('betTogether', ['ui.router']);
route.js
angular.module('betTogether').config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider){
// For any unmatched url, send to /business
$urlRouterProvider.otherwise("/descriptionBets")
$stateProvider
.state('descriptionBets', {//State demonstrating Nested views
url: "/descriptionBets",
templateUrl: "descriptionBets",
controller: "descriptionBetsCtrl"
})
.state('normalBets', {//nested state [products is the nested state of business state]
url: "/normalBets",
templateUrl: "normal",
controller: "normalBetsCtrl"
})
.state('addBet', {//nested state [services is the nested state of business state]
url: "/addBet",
templateUrl: "addBet",
controller: "addBetCtrl"
});
}]);
and it doesnt work. i have error:
Error: [$injector:nomod] http://errors.angularjs.org/1.3.10/$injector/nomod?p0=betTogether angular.min.js:6:417
... and it is for 1st line of each controllers.
Someone could help me?
PS: sorry for my english, hope You understand all.
Check the order of your <script> imports in your index.html. The likelihood is that you've included the ui-router module after your betTogether module whereas it should come before it because betTogether depends on ui.router.
I am new to angular and ionic, my app information goes like this: I have a splash screen on which I have my login page,followed by home screen.Now the problem is if the user has logged in once,then whenever the app is closed and opened again it shows the login screen,instead it should show home screen. How do I achieve that. I have tried many solutions, but none of them worked. Kindly help.
var kit = angular.module('starter', ['ionic','ionic.service.core', 'ngCordova']);
kit.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('start', {
url: '/',
templateUrl: 'templates/start.html',
controller: 'StartController'
})
.state('home', {
url: '/home',
templateUrl: 'templates/home.html',
controller: 'HomeController'
})
.state('scrollView', {
url: '/scroll',
templateUrl: 'templates/ScrollEx.html',
controller: 'ScrollExController'
})
.state('check', {
url: '/check',
templateUrl: 'templates/check.html',
controller: 'CheckController'
})
$urlRouterProvider.otherwise('/');
});
In your login page's controller, I assume this is StartController, you can use something like:
// Note you need $location for navigation here:
app.controller('StartController', ['$rootScope', '$scope', '$location', /*...*/
function ($rootScope, $scope, $location /*...*/) {
// Test condition, just an example:
if (sessionStorage.user.id) {
$location.path('/home');
}
// Controller code goes here
});
This is assuming you condition is sessionStorage.user.id.
Angular's $location will handle router navigation elegantly for you.
Source: AngularJS: $location
So I am using ui-view to route me to a partial.
//route.provider.js
(function() {
'use strict';
angular
.module('app')
.provider('RouteService', RouteService);
RouteService.$inject = ['$stateProvider', '$urlRouterProvider'];
function RouteService ($stateProvider, $urlRouterProvider) {
var service = {};
this.$get = function() { return service; };
this.initialize = function() {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('home', {
url: '/home',
controller: 'HomeController',
templateUrl: 'home/home.view.html',
controllerAs: 'viewModel'
})
.state('login', {
url: '/login',
controller: 'LoginController',
templateUrl: 'login/login.view.html',
controllerAs: 'viewModel'
})
//TODO Impliment the following partial pages...
.state('gensim', {
url: '/gensim',
templateUrl: 'general-simulation/simulation.view.html',
controller: 'TabsController',
controllerAs: 'tabs'
})
<...more routes...>
}
}
})();
The issue I am having is once it routes to
// general-simulation/simulation.view.html
I'd like it to use a custom directive to insert more html into the page.
Inside simulation.view.html I have this.
<div class="container">
<div class="row center">
<div class="col-xs-12">
<h1>General Simulation</h1>
<gs-tabs><h1>TEST!!!!</h1></gs-tabs>
</div>
</div>
</div>
The directive is constructed in
// tabs.directives.js
(function(){
'use strict';
angular
.module('app')
.directive('gsTabs', gsTabs);
function gsTabs () {
return {
restrict: "E",
templateURL: 'tabs.view.html'
};
}
})();
Finally, my tabs.view.html looks like this.
<h1>YOU HAVE ENTERED TABS PARTIAL</h1>
When I navigate to the page that displays simulation.view all I can see is:
General Simulation
TEST!!!!
So what am I doing wrong here. I checked for camelCasing and the page is not showing in errors. Any help would be greatly appreciated!
Update:
I viewed the network calls in chrome's dev tools.
simulation.view.html is being loaded but tabs.view.html isn't.
Request URL:http://sdc-stagt01/AngularJS/general-simulation/simulation.view.html
Request Method:GET
Status Code:200 OK
Remote Address:10.19.8.96:80
The file substructure is:
/general-simulation/tabs/tabs.controller.js
/general-simulation/tabs/tabs.directives.js
/general-simulation/tabs/tabs.view.html
/general-simulation/simulation.view.html
putting comment as answer
change templateURL to templateUrl
So entre's comment was a big help. That got chrome dev to start spitting out errors.
charlietfl Was on the right track with mentioning my file structure as well. I needed to change my directive to look like this:
templateUrl: 'general-simulation/tabs/tabs.view.html'
Thank you!
You have a typo here. templateUrl not templateURL
function gsTabs () {
return {
restrict: "E",
templateURL: 'tabs.view.html' // change this to templateUrl
};
}
I am setting up a scaffold for an app with angular and angular-ui-router. I have it working however it seems to be adding a hash into my url (I'm running dev on localhost) localhost:9000/#/test. When I land on the main page it's just localhost:9000 and it still serves the main view content. I would like to get rid of the hash if possible.
So here is my setup:
In my index.html in the body I just have my nav and then the ui-view under that:
<div class="row">
<ul class="nav navbar-nav">
<li><a ui-sref="index">Home</a></li>
<li><a ui-sref="test">Test</a></li>
</ul>
</div>
<div ui-view=""></div>
and in my app.js I just have:
angular
.module('playApp', [
'ui.router'
])
.config(function($stateProvider) {
$stateProvider
.state('index', {
url: '',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.state('test', {
url: '/test',
templateUrl: 'views/test.html',
controller: 'testCtrl'
});
});
So when I land, it's fine, but when I start using the nav I have set up, it adds the hashes to the url, would prefer not to have them if possible. Thanks!
Include $locationProvider and do $locationProvider.html5Mode(true); :
angular.module('playApp', ['ui.router'])
.config(function($stateProvider, $locationProvider) {
$stateProvider.state('index', {
url: '',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.state('test', {
url: '/test',
templateUrl: 'views/test.html',
controller: 'testCtrl'
});
$locationProvider.html5Mode(true);
});
I also have an otherwise in there as well, so that if it can't find a specified route, it will just default back:
angular.module('playApp', ['ui.router'])
.config(function($stateProvider, $locationProvider, $urlRouterProvider) {
$stateProvider.state('index', {
url: '',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.state('test', {
url: '/test',
templateUrl: 'views/test.html',
controller: 'testCtrl'
});
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/');
});
Inject $locationProvider into your config and set html5mode to true:
angular.module('playApp', [
'ui.router'
])
.config(function($stateProvider, $locationProvider ) {
$stateProvider
.state('index', {
url: '',
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.state('test', {
url: '/test',
templateUrl: 'views/test.html',
controller: 'testCtrl'
});
$locationProvider.html5Mode(true);
});
Make sure you adjust your .htaccess to handle this (rewriting back to root).
There is an alternative to html5Mode. But it has its drawbacks.
When defining ui-router states, the url option is not required. From that documentation:
You might create some child states without URLs, if it doesn’t make sense to bookmark those child states. The state machine transitions between url-less states as usual, but does not update the url when complete. You still get all the other benefits of a state transition such as parameters, resolve, and lifecycle hooks.
If you don't need to provide a URL for a state so that users can bookmark those states, you can omit the url option. The URL won't change.
I am trying to do what was essentially answered here Unable to open bootstrap modal window as a route
Yet my solution just will not work. I get an error
Error: [$injector:unpr] Unknown provider: $modalProvider <- $modal
My app has the ui.bootstrap module injected - here is my application config
var app = angular.module('app', ['ui.router', 'ui.bootstrap','ui.bootstrap.tpls', 'app.filters', 'app.services', 'app.directives', 'app.controllers'])
// Gets executed during the provider registrations and configuration phase. Only providers and constants can be
// injected here. This is to prevent accidental instantiation of services before they have been fully configured.
.config(['$stateProvider', '$locationProvider', function ($stateProvider, $locationProvider) {
// UI States, URL Routing & Mapping. For more info see: https://github.com/angular-ui/ui-router
// ------------------------------------------------------------------------------------------------------------
$stateProvider
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
.state('transactions', {
url: '/transactions',
templateUrl: '/views/transactions',
controller: 'TransactionsCtrl'
})
.state('login', {
url: "/login",
templateUrl: '/views/login',
controller: 'LoginCtrl'
})
.state('otherwise', {
url: '*path',
templateUrl: '/views/404',
controller: 'Error404Ctrl'
});
$locationProvider.html5Mode(true);
}])
I have reduced my controller to the following:
appControllers.controller('LoginCtrl', ['$scope', '$modal', function($scope, $modal) {
$modal.open({templateUrl:'modal.html'});
}]);
Ultimately, what I am hoping to achieve is when login is required not actually GO to the login page, but bring up a dialog.
I have also tried using the onEnter function in the ui-router state method. Couldn't get this working either.
Any ideas?
UPDATE
Ok - so as it turns out, having both ui-bootstrap.js AND ui-bootstrap-tpls breaks this - After reading the docs I thought you needed the templates to work WITH the ui-bootstrap. though it seems all the plunkers only load in the ..tpls file - once I removed the ui-bootstrap file my modal works...Am i blind? or doesn't it not really say which one you need in the docs on github? -
Now i just need to figure out how to prevent my url from actually going to /login, rather than just show the modal :)
update 2
Ok, so by calling $state.go('login') in a service does this for me.
Hi I had a hard time getting through the similar problem.
However, I was able to resolve it.
This is what you would probably need.
app.config(function($stateProvider) {
$stateProvider.state("managerState", {
url: "/ManagerRecord",
controller: "myController",
templateUrl: 'index.html'
})
.state("employeeState", {
url: "empRecords",
parent: "managerState",
params: {
empId: 0
},
onEnter: [
"$modal",
function($modal) {
$modal.open({
controller: "EmpDetailsController",
controllerAs: "empDetails",
templateUrl: 'empDetails.html',
size: 'sm'
}).result.finally(function() {
$stateProvider.go('^');
});
}
]
});
});
Click here for plunker. Hope it helps.
I'm working on something similar and this is my solution.
HTML code
<a ui-sref="home.modal({path: 'login'})" class="btn btn-default" ng-click="openModal()">Login</a>
State configuration
$stateProvider
// assuming we want to open the modal on home page
.state('home', {
url: '/',
templateUrl: '/views/index',
controller: 'HomeCtrl'
})
// create a nested state
.state('home.modal', {
url: ':path/'
});
Home controller
//... other code
$scope.openModal = function(){
$modal.open({
templateUrl: 'path/to/page.html',
resolve: {
newPath: function(){
return 'home'
},
oldPath: function(){
return 'home.modal'
}
},
controller: 'ModalInstanceController'
});
};
//... other code
Finally, the modal instance controller.
This controller synchronizes the modal events (open/close) with URL path changes.
angular.module("app").controller('ModalInstanceController', function($scope, $modalInstance, $state, newPath, oldPath) {
$modalInstance.opened.then(function(){
$state.go(newPath);
});
$modalInstance.result.then(null,function(){
$state.go(oldPath);
});
$scope.$on('$stateChangeSuccess', function () {
if($state.current.name != newPath){
$modalInstance.dismiss('cancel')
}
});
});
You may create a state with the same templateUrl and controller as your page where you want to show the modal, adding params object to it
$stateProvider
.state('root.start-page', {
url: '/',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl'
})
.state('root.login', {
url: '/login',
templateUrl: 'App/src/pages/start-page/start-page.html',
controller: 'StartPageCtrl',
params: {
openLoginModal: true
}
})
And in controller of the page, use this parameter to open the modal
.controller("StartPageCtrl", function($scope, $stateParams) {
if ($stateParams.openLoginModal) {
$scope.openLoginModal();
}
I found a handy hint to get this working. There are probably caveats, but it works for me. You can pass a result still but I have no need for one.
Using finally instead of the then promise resolve sorted this for me. I also had to store the previous state on rootScope so we knew what to go back to.
Save previous state to $rootScope
$rootScope.previousState = 'home';
$rootScope.$on('$stateChangeSuccess', function(ev, to, toParams, from, fromParams){
$rootScope.previousState = from.name;
})
State using onEnter
$stateProvider.state('contact', {
url: '/contact',
onEnter: function ($state, $modal, $rootScope){
$modal.open({
templateUrl: 'views/contact.html',
controller: 'ContactCtrl'
}).result.finally(function(){
$state.go($rootScope.previousState);
})
}
});