URL is not changing even after the state is changed . `ui-router` - angularjs

I am using ui-router and state provider to route the pages in my application. I have following states written in state provider.
.state('home', {
url: '/home',
templateUrl: 'public/msStream/stateFiles/stateHome.html',
controller: 'stateHomeController'
})
.state('home.profile', {
url: '/home/profile',
templateUrl: 'public/msStream/views/setting/ProfileBody.html'
})
When I am in home state. /home is added in my URL, but when I switch to home.profile state using $state.go("home.profile), my URL is not changing to /home/profile but HTML page added in templateurl of the same state is getting rendered on front.
I tried adding /profile and /home/profile in the URL of the state but nothing seems to work. What am I missing here?

I created working plunker here
The paren-child states do inherit a lot. Among other things, also the url. So we should not use for child the url part coming from parent.
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'public/msStream/stateFiles/stateHome.html',
controller: 'stateHomeController'
})
.state('home.profile', {
// HERE
// instead of this
// url: '/home/profile',
// we need this
url: '/profile',
templateUrl: 'public/msStream/views/setting/ProfileBody.html'
})
Also very improtant note - parent must contain anchor/target/ui-view for its child:
public/msStream/stateFiles/stateHome.html
<div>
<h2>this is the home</h2>
placeholder for child:
<hr />
<div ui-view=""></div>
</div>
The most important here is the <div ui-view=""></div> - a placeholder for child view (unnamed)
Check it in action here

Related

AngularJS ui-view nested routes with url parameters on parent

I'm trying to use angular ui-router in my project and I'm running into an issue about maintaining url parameters in the parent route while adding child ones...
I have a settings page with the following route: /settings/:messageCode/:status
And now I need to add a piece of template that changes depending on the route so the new display looks like this: https://imgur.com/a/dHKzVD6
<div>
<div id="sidebar">...</div>
<div id="topbar">...</div>
<div ui-view>
<!-- This is the variable content depending on the route -->
</div>
</div>
The new routes I need to add are the following:
/settings/studio
/settings/payments
And this is my code for the nested routing
...
$stateProvider
.state("register", {...})
.state("settings", {
url: "/settings", // the objective is to keep the previous route "/status/:messageCode/:status"
templateUrl: 'settings/settings.view.html',
controller: 'SettingsCtrl as vm',
params: {
messageCode: {
value: null,
squash: true,
dynamic: true,
},
success: {
value: null,
squash: true,
},
})
.state("settings.studio", {
url: "/studio",
templateUrl: 'template-tab-studio.html',
controller: 'SettingsCtrl as vm',
})
.state("settings.payments", {
url: "/payments",
templateUrl: 'template-tab-payments.html',
controller: 'SettingsCtrl as vm',
})
At the moment, the routing is working fine, but I lost the URL params on the parent component (settings home), while adding its new children without having to add the url parameters to all childrens.
The problem of having to add the URL params to all children, is that I'll need to add many more views, so having to maintain all that routes will complicate things.
Is there a way to keep the original route in the parent (/settings/:messageCode/:status) while adding children so they can also recieve that paremeters?
Target routes would look like this: /settings/{dinamicView}/:messageCode/:status.
can't get what parameters do you mean, to pass variables to child route you could use resolve
to keep previous route change url: "/settings" to url: "settings"

Issue with using the same template for different states on ui-router

I'm trying to use the same template for 2 different views. My set up is this
$stateProvider.state('me', {
url: '/me',
templateUrl: 'partial/profile/profile.html',
controller: 'ProfileController'
});
$stateProvider.state('myteam', {
url: '/myteam',
templateUrl: 'partial/myteam/myteam.html',
controller: 'MyteamController'
});
$stateProvider.state('myteam.teamMember', {
url: '/:username',
templateUrl: 'partial/profile/profile.html',
controller: 'ProfileController'
});
However whenever I try and access myteam.teamMember, the URL changes but the view doesn't change. Anyone have any advice?
When you redirect to child state it looks for ui-view(it can be named view) on current state HTML, and load the state template in it. Basically you are redirecting to child state of myteam, so to get the changes on view you should have ui-view somewhere inside partial/myteam/myteam.html HTML file.
partial/myteam/myteam.html
<div>
MY HTML
......
.......
<div ui-view></div>
</div>

AngularJS - Default view in <ui-view> element

Is there any problem putting default code inside of a <ui-view> element. It appears to work, but I can't find anything saying one way or another if it's okay to use or not.
My current usage is I want the "default" view to be a list of items. Upon clicking one of those items, it switches to an "editor" child state, which replaces the <ui-view> content with the editor child.
Are there any gotchas I should be aware of before continuing with this approach?
Here is an example of what I'm looking at:
routes.js:
.config(($stateProvider) => {
$stateProvider
.state('admin', {
url: '/admin',
templateUrl: 'admin.html'
})
.state('admin.items', {
url: '/admin/items',
templateUrl: 'admin.items.html'
})
});
admin.html:
<ui-view>Default Stuff Here</ui-view>
items.html:
<p ng-repeat="item in items">{{item}}</p>
Now, I know I can do:
.state('admin.default', {
url: '',
templateUrl: 'admin.default.html'
});
And then put that would show in ui-view. However, that needlessly adds a new state and template file, when it seems to work just fine putting the would-be contents of admin.default.html directly into the ui-view of admin.html.
In my case, I'm not talking about a completely stateless option using otherwise(), I'm talking about a defined parent state with a default child state.
We generally do not put anything inside <ui-view></ui-view>, instead we create a default state and use that.
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'home.html'
})
.state('about', {
// we'll get to this in a bit
});
});
Here the default one is /home, like that you can create a default one.
First, As said in the other answer, we never give any data within the ui-view.. But while dealing with the ui-router, you should give all the specific states in .config()
app.config(function($stateProvider,$urlRouterProvider){
$stateProvider
.state('home',{
url : '/home',
controller: 'homeCtrl',
templateUrl : 'home.html'
}).state('login',{
url : '/login',
controller: 'loginCtrl',
templateUrl : 'login.html'
});
//AND HERE YOU PROVIDE THE DEFAULT PLACE WHERE THE USER IS TO BE REDIRECTED
//IN CASE OF IMPROPER URL
$urlRouterProvider.otherwise('/login');
});
Secondly, If you want to use the <ui-view></ui-view> to hold some data, you certainly can put some data within them.. But make sure that from the state you define, It should not supply any template or templateUrl. So the data within the <ui-view></ui-view> stays as it is.
And third.. Why to keep a default state..
in case you are defining a state admin in your config(), and then in your admin.routes.js file you can define a state as follows..
.state('admin.login',{
url:'',
controller:'loginCtrl',
templateUrl:'admin.login.html'
});
So in case the url is YOURURL/admin It will directly open the login page by default.. so there is no chance of redundancy...

Angular ui-router subview issues

I've been working with Angular for a year or 2 now, but this is my first project using ui-router. I'm running into a few issues with views and sub-views. The app is a standard left-side menu bar, with the views on the right changing depending on what's clicked in the menu bar.
On index.html
<body>
<div ui-view></div>
</body>
In the config.js file, which defines the routes
.state("dashboard", {
url: "/dashboard",
templateUrl: "components/dashboard/dashboard.html",
data: {
pageTitle: "Dashboard",
requiresLogin: false
}
})
.state("dashboard.welcome", {
url: "/welcome",
templateUrl: "components/welcome/welcome.html",
data: {
pageTitle: "Welcome",
requiresLogin: false
}
})
In the dashboard.html file
<div class="dashboard">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12 col-md-8">
<div ui-view>
The /dashboard path loads correctly, and will load the left-side navigation bar with a blank right side. But changing the state to dashboard.welcome (/welcome) will not load the welcome.html template.
Whenever working with ui-router you need to understand that the concept of states is different from routes. When you define a sub-state, its defined relative to its parent state. In your scenario dashboard.welcome is defined as a child state of dashboard. The routes to substate is relative to the parent and is {parent url}/{child url}. Hence you should use either of the below 2 to route to that state:
Using $state.go change the state by specifying state name
$state.go('dashboard.welcome');
Using $location.path change the route by specifying url
$location.path('/dashboard/welcome');
It sounds like you want links to /welcome to be for state dashboard.welcome. Here is a plunker showing how this can be done. I show two sets of dashboard and welcome states. The first set of states (dashboard & welcome) shows that /dashboard/welcome will bring you to the dashboard.welcome state.
The second set (dashboard2 & welcome2) shows that /welcome will go to state dashboard2.welcome2. I believe this is what you were looking for.
If you hover over the links you can see where they will take you.
https://plnkr.co/edit/AVKPFa?p=info
Nested routes in ui-router get nested urls. I would however recommend using named-views for this kind of structure. You can find more info about it here:
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
The gist of it is: you can specify a named component (ui-view) for your left menu navigation and another one for content, which gives you much more control down the line, because named components can be overwritten in child states or they can keep the default template, depending on your needs.
Example:
.state('root', {
url: '',
abstract: true,
views: {
'header': {
templateUrl: 'templates/partials/header.html',
controller: 'headerCtrl'
},
'logo': {
templateUrl: 'templates/partials/logoView.html'
},
'footer':{
templateUrl: 'templates/partials/footer.html',
controller: 'footerCtrl'
}
}
})
.state('root.login', {
url: '/login',
views: {
'header#': {
template: ''
},
'container#': {
templateUrl: 'templates/login.html',
controller: 'loginController'
}
}
})
.state('root.report', {
url: '/report',
views: {
'container#': {
templateUrl: 'templates/eu_dashboard.html',
controller: 'reportController'
}
}
})
And in your index.html:
<div ui-view="logo"></div>
<div ui-view="header"></div>
<div id="mainView" ui-view="container"></div>
<div ui-view="footer"></div>

AngularJS ui-router with different URL parameters

While using ui-view in AngularJS, I'm trying to use URL parameters inside of nested views.
For entities of a given type, I want to be able to show all of the entities when navigating to the url /entities, but I would also like to see only the entities of a given type if I go to entities/ofcategory/categoryName. Lastly, I also want to be able to navigate to /entities/details/entityName to see the details of one entity.
Is this structure possible?
This is my ui-routercode:
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('entities', {
url: '/entities',
templateUrl: 'app/entities/views/entities.html'
})
.state('entities.ofcategory', {
url: '/ofcategory/:categoryName',
templateUrl: 'app/entities/views/entities.ofcategory.html'
}
.state('entities.details', {
url: '/details/:entityName',
templateUrl: 'app/entities/views/entities.details.html'
});
}]);
If I'm navigating to entities/ofcategory/aname or /entities/details/aname I enter the regular entities controller instead of the category or detailsController
One option is to add an abstract state, which serves as a parent to all your entities states. In that case all your urls become relative to this parent state. Please note that you have to define a ui-view in the template of the abstract state, so it could be used for loading the child templates.
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('entities', {
url: '/entities',
abstract: true,
templateUrl: 'app/entities/views/entities.html'
})
.state('entities.all', {
url: '/',
templateUrl: 'app/entities/views/entities.all.html'
})
.state('entities.ofcategory', {
url: '/:categoryName',
templateUrl: 'app/entities/views/entities.ofcategory.html'
}
.state('entities.details', {
url: '/details/:entityName',
templateUrl: 'app/entities/views/entities.details.html'
});
}]);
app/entities/views/entities.html:
<div>
<h1>Entities<h1>
<div ui-view></div>
</div>

Resources