url change not triggering state change with angular ui router - angularjs

I'm using angular ui router to create a home route like this
routes.$inject = ['$stateProvider'];
export default function routes($stateProvider) {
$stateProvider
.state('home', {
url: '/',
template: require('./home.html'),
controller: 'HomeController',
controllerAs: 'home'
})
In the HomeController, I'm importing a service that provides a stream of blog posts. Thus, in the ./home.html template, I am iterating through the array of posts like this, creating links for each post
<span ng-repeat="post in home.posts">
<a ui-sref="home.detail({postId:post.id})">{{post.title.rendered}}</a>
</span>
As you can see from the link, I'm expecting a click of the link to be handled by home.detail state. In the router, I do this, expecting each post to have a url (when I click the links) something like http://localhost:8888/1 or http://localhost:8888/4. However, when I click the links, the url changes but the ./post.html template doesn't load and the log statement in the controller code below doesn't run. There are no errors in the console.
Question: why is the router code to handle the click of the individual links (to load the new template, to log the stateParams) not running when I click the links to the posts (yet the url changes)?
$stateProvider
.state('home', {
url: '/',
template: require('./home.html'),
controller: 'HomeController',
controllerAs: 'home'
})
.state('home.detail', {
url: '{postId:[0-9]{1,4}}',
template: require('./post.html'),
controller: ['$scope', '$stateParams',
function ( $scope, $stateParams) {
console.log($scope, "$scope", $stateParams, "$stateParams");
$scope.post = $stateParams;
}],

Your parent state needs a ui-view. From ui-router's documentation
Child states will load their templates into their parent's ui-view.

Related

Angular UI-Router childs

I have an app.config with UI-Router. It has a login page with it's controller, recoverLogin and I want to put a template with footer, header and more stuff with new states that could be loaded into the template (in an especificplace).
My module is:
var app = angular.module("app", [
"ui.router",
"pascalprecht.translate"
]);
My routes are;
app.config(function($stateProvider, $urlRouterProvider)
{
$stateProvider
.state("login", {
url: "/login",
templateUrl: "views/accessControl/login.html",
controller: "loginCtrl"
});
$stateProvider
.state("recoverLogin", {
url: "/recoverLogin",
templateUrl: "views/accessControl/recoverLogin.html",
controller: "recoverLoginCtrl"
});
$stateProvider
.state("template", {
url: "/template",
templateUrl: "views/templates/template.html",
controller: "templateCtrl"
})
.state("template.dashboard", {
url: "/dashboard",
templateUrl: "views/dashboard/dashboard.html",
controller: "dashboardCtrl"
})
$urlRouterProvider.otherwise("login");
})
I have in my index <ui-view></ui-view> for the place of the loadings and another <ui-view></ui-view> in template.html int he place where I want to load more stuff like dashboard.html, but this doesn't works. it loads dashboard.html without the template created in template.html. I have founded lot of documentation that doesn´t works for me. Any Idea?
Here there are a plunker example of the idea: https://plnkr.co/edit/ZsGZjDKOBTIXFpPtXasN?p=preview
There is updated plunker and working plunker.
The template of the mainTemplate state is now lookin like this:
place for main:
<div ui-view="main"></div>
place for other:
<div ui-view="other"></div>
so it has two (could be more) places for more stuff. And this is the state redefined:
.state("mainTemplate.dashboard", {
name: "main",
url: "/dashboard",
views: {
'main' : {
templateUrl: "dashboard.html",
controller: "dashboardCtrl"
},
'other' : {
template: "<h2>other view</h2>",
}
}
});
What we can see is views : {} object being used to defined multiple content for more targets. Read about that more details here:
Angular UI Router - Nested States with multiple layouts
Nested states or views for layout with leftbar in ui-router?
play or observe the changes here

Route to Submenu Angularjs

In this sample what I need is that in plnkr.co/edit/5FVrydtTPWqYMhhLj03e?p=preview, when I click the Contact Numbers button, It will redirect to the Contact Numbers page in the Contacts.
Im using Angular JS and I hope someone can help me.
scotchApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the about page
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl : 'pages/contact.html',
controller : 'contactController'
});
});
Credits to https://scotch.io/tutorials/angular-routing-using-ui-router for I am forking their example
Your code shows a ng-route example but the link you provide is a ui-router example. ($routeProvider vs $stateProvider).
If you would be using the $stateProvider from angular-ui-router to define the states you'll be using throughout your application it would probabably be more like the following:
$stateProvider.state('home', {
controller: 'mainController',
url: '/',
templateUrl: 'pages/home.html'
});
$stateProvider.state('about', {
controller: 'aboutController',
url: '/about',
templateUrl: 'pages/about.html'
});
$stateProvider.state('contact', {
controller: 'contactController',
url: '/contact',
templateUrl: 'pages/contact.html'
});
You see that a definition of a state uses a string to identify itself with: e.g. :'home', 'contact' etc. You can use the $state service from ui-router and use the \[go(to, params, options)\] method to transition between states in combination with this identifier.
Convenience method for transitioning to a new state. $state.go calls
$state.transitionTo internally but automatically sets options to {
location: true, inherit: true, relative: $state.$current, notify: true
}. This allows you to easily use an absolute or relative to path and
specify only the parameters you'd like to update (while letting
unspecified parameters inherit from the currently active ancestor
states).
All you need to do is to couple this to the click event of you button in your maincontroller. That is: inject $state into your mainController and couple an ng-click within your button to a function that executes $state.go().
<button type="submit" ng-click="$state.go('contact')">Contact Numbers</button>

$state.go not redirecting but its loading the content with 200 OK

Here is the plunker link for the code http://plnkr.co/edit/JwM8t3oNepP3tE1nUXlM?p=info
controller.js
if(($scope.login==='Admin')&&($scope.password==='admin'))
{
$state.go('login.home');
}
script.js
var DailyUsageApp = angular.module('DailyUsageApp', ['ui.router']);
DailyUsageApp.config(function($stateProvider, $locationProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider.state('login', {
url: '/login',
templateUrl: "login.html",
controller: 'authController'
})
.state('login.home', {
url: '/home',
templateUrl: "home.html",
controller: 'homeController'
});
});
The reason your code isn't working is because you are creating hierarchical states, that are not meant to be hierarchical. By naming your state login.home, you are saying that home is a child of login. This means that when you try and go('login.home') ui router is attempting to render the login state as well as the home state as a child. This means that for your current layout to work, the login template must contain its own ui-view tag. The best way to fix this is to simply rename your state to just home, and then use $state.go('home');
There is an updated plunker
The most simple solution is to NOT make state login.home nested under login.
//.state('login.home', {
.state('home', {
url: '/home',
templateUrl: "home.html",
controller: 'homeController'
});
There are also other solutions, like create a target for login.home inside of the login like this:
<div ui-view=""></div
But usually, we do not do that. Just login and then navigate to some other state hierarchy...

Failed to load parent route in angular UI-Router

In my app I have some main modules and each modules has sidebar.
If I click sidebar item then it will route to sidebar linking page but here if I click header again then I am not able to view my parent route page.
I have listed my problem in this plnkr.
Step to reproduce :
By default route1 is selected and dashboard is available on view. Click on Item1.
Now click on route1 : Failed to see dashboard view.
<script>
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider, $urlRouterProvider) {
// For any unmatched url, send to /route1
$urlRouterProvider.otherwise("/route1")
$stateProvider
.state('route1', {
url: "/route1",
templateUrl: "route1.html",
controller: function($scope, $state) {
$scope.items = ["item1", "item2"];
$state.go('route1.dashboard');
}
})
.state('route1.dashboard', {
url: "/dashboard",
templateUrl: "dashboard.html"
})
.state('route1.item1', {
url: "/item1",
templateUrl: "item1.html"
})
.state('route1.item2', {
url: "/item2",
templateUrl: "item2.html"
})
.state('route2', {
url: "/route2",
templateUrl: "route1.html",
controller: function($scope, $state) {
$scope.items = ["item3", "item4"];
$state.go('route2.dashboard');
}
})
.state('route2.dashboard', {
url: "/dashboard",
templateUrl: "dashboard.html"
})
.state('route2.item3', {
url: "/item3",
templateUrl: "item3.html"
})
.state('route2.item4', {
url: "/item4",
templateUrl: "item4.html"
})
})
</script>
The code you have in the route1 controller only runs when it's instantiated. Therefore, after you re-visit it from being inside item1, it doesn't need to reload and the $state.go() doesn't fire.
I've forked your plunker with another potential approach: http://plnkr.co/edit/7stMErnkb3rzPJD0Gj5x?p=preview
you should put the dashboard content in the route1 template, rather than attempting to forward to it via $state.go()
so, your route1.html goes from the previous ui-view statement of
<div ui-view></div>
to
<div ui-view>
<h1>Dashboard</h1>
</div>
Now you don't need the dashboard partial, and it loads every time. The item1/item2 partials will replace the content in the ui-view whenever those states activate.
Note in the updated Plunker how Route1 works as you want, while Route2 still doesn't work (as it still has the previous $state.go() approach).

UI-Router using routes within a Section of a Site

The site I'm building already has URL's built up using MVC. So for example /Account goes to a page, /Customers goes to a page, and /Quotes goes to a page. On the /Quotes page I have a multi-step wizard which I want to use Ui-Routing on. See my app.js below, this all works.
So my URL becomes /Quotes#newmodel, /Quotes#customer, etc. A different #{value} for each step on the wizard. The problem is that the .otherwise affects all other areas of the site. So if I'm going to /Account, I get the url /Account#wizard. I do not want this to occur anywhere other than on the /Quotes page. Is there anything I can do with the URL matching so I can remove the .otherwise?
'use strict';
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/wizard");
$stateProvider
.state('wizard', {
url: '/wizard',
templateUrl: 'Scripts/templates/wizardLayout.html',
controller: 'wizardNavigationCtrl'
})
.state('wizard.newmodel', {
url: '/newmodel',
templateUrl: 'Scripts/templates/wizardModel.html',
controller: 'wizardModelCtrl'
})
.state('wizard.other', {
url: '/other',
templateUrl: 'Scripts/templates/wizardOther.html',
controller: 'wizardOtherCtrl'
})
.state('wizard.customer', {
url: '/customer',
templateUrl: 'Scripts/templates/wizardCustomer.html',
controller: 'wizardCustomerCtrl'
})
.state('wizard.shipping', {
url: '/shipping',
templateUrl: 'Scripts/templates/wizardShipping.html',
controller: 'wizardShippingCtrl'
})
.state('wizard.review', {
url: '/review',
templateUrl: 'Scripts/templates/wizardReview.html',
controller: 'wizardReviewCtrl'
});
}]);
I'm also interested in how I can cause the route to load the layout and then by default go to the wizard.newmodel route (though this may be a separate question). Basically the same behavior as if I click on an:
<a sref-ui=".newmodel">
I removed the $urlRouterProvider.otherwise("/wizard") in the app.js.
Instead I added a controller to the main /Quote page that redirects the $location.url to '/wizard'. Below is the code.
myApp.controller('wizardCtrl', ['$location', function ($location) {
$location.url('wizard')
}])

Resources