UI router cannot resolve state error message - javascript

I am working on angular application at the moment, using ui-router and I am getting the following error message.
Error: Could not resolve 'static.about' from state 'static'
and I am not sure why. What I am wanting to achieve is to have 2 sections to my application, the static section, homepage, about, login, register and the app side which would things like dashboards, user profiles etc I thought I would need to set up my ui-router like this,
app
.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider){
// any unknown URLS go to 404
$urlRouterProvider.otherwise('/404');
// no route goes to index
$urlRouterProvider.when('', '/home');
// use a state provider for routing
$stateProvider
.state('static', {
url: '/home',
templateUrl: '',
views : {
header : {
templateUrl : 'app/components/shared/header.html'
},
main: {
templateUrl : 'app/components/home/views/home.view.html'
}
}
})
.state('static.about', {
// we'll add another state soon
url: '/about',
templateUrl: 'app/components/about/views/about.view.html',
})
.state('app', {
abstract: true,
templateUrl: ''
})
.state('app.dashboard', {
url: 'app/dashboard',
templateUrl : '',
})
}]);
However this returns the error already mentioned. The reason I am wanting to set it up like this that the 2 sides to application also have very different layouts, so I figured that I should be able push different layouts into my ?
The biggest problem I am having however is the error, and secondly the links being generated, when I click on about it should go to /about, however it is going to /home/about.
All I am wanting to achieve in the early stages is for my "static" pages to share a nav and have interchangeable main section, and for "app" pages to have a completly new layout/parent template

You need to set the parent property on the children views.
.state('static.about', {
url : '/about',
templateUrl : 'app/components/about/views/about.view.html',
parent : 'static'
})
Also check the answer to this question Angular ui-router : Parent & Child Views.
I guess that when you do $state.go(static.about) it just goes to homepage since you are doing an otherwise or something similar.
Like : $urlRouterProvider.when('', '/home');
Angular-Ui-Router resolves the main route when something isn't okay.
Also pay attention to the extra , you are adding at the end of templateUrl.

The above construction of states is ok. I created a plunker to demonstrate it here
In a root state 'static' we just do not use templateUrl.. it would be skipped anyhow, because we do define views : {}
.state('static', {
url: '/home',
// we want to have views : {} so avoid this shorthand template
// templateUrl: '',
views: {
header: {
templateUrl : 'app/components/shared/header.html',
},
main: {
templateUrl : 'app/components/home/views/home.view.html',
}
}
})
And a child state 'static.about' can use '^' leading sign, to reset its url from root
.state('static.about', {
// here we use a switch to inform - this url starts from root
//url: '/about',
url: '^/about',
templateUrl: 'app/components/about/views/about.view.html',
})
And with these calls, all is working
<a ui-sref="static">
<a ui-sref="static.about">
Check it in action here
The Error message:
Error: Could not resolve 'static.about' from state 'static'
Usually happens, if we have a typoe in state definition (or calling side). But that is not the issue. Or if we omit to load definition file...

To me it seems that, you don't want to define a completely new UI when going to static.about but use the header from static.
Remove the templateUrl from static.about
Add a property view that should be an object with a property called "main#static" and the value should be another object with your templateUrl.
More info: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

Related

AngularJS ui route hash prefix

I am using AngularJS ui route for routing I want to remove # (hash from URL). I am using this code and also using (base href="/") in my index.html file. It's working fine but when I refresh the page like (http://0.0.0.0:3000/athletepersonalinfo) it's giving me an error.
.config(function($stateProvider,$locationProvider) {
$locationProvider.html5Mode({ enabled: true, requireBase: false })
$stateProvider
.state('/', {
url: '',
templateUrl:HTML.HOME,
controller: 'homeController as home'
})
.state('home', {
url: '/',
controller: 'homeController as home',
templateUrl: HTML.HOME
})
.state('athletepersonalinfo', {
url: '/athletepersonalinfo',
controller: 'athleteProfileInfo',
templateUrl: HTML.ATHLETE_PERSONAL_INFO,
authenticate: true
})
When you hit refresh the server actually tries to find if the given route has been defined /athletepersonalinfo. To actually remove the # from the url you will have to include a get(/*) route which would always return your index.html page. This route should be after all other routes. Now what this means is your index.html will be served whenever no routes is defined than in your client side angular will handle which view to load. Few points to note when making such chages
Since any unresolved get could return your index.html make sure your routes are meaningful like all your assets start with /assets/ path, all your api calls start with /api/ .
The benefit in doing so is if you get a 404 on some assets or an api call you would still get your index.html which is wrong. But with this approach all you need to do is set a route something like this
app.get('/:url(api|assets)/*',function(req,res){
res.status(400).send("Not Found")
});
app.get('/*',function(req,res){
res.sendFile('index.html');
});
Make sure the * route is defined after all other routes else you will keep getting index.html for every request.
Hope this helps.

Ui router AngularJs Nested states and Nested views correct way

here's the repo: https://github.com/vipul-verma/LetsLearnAngular
here's the live view: https://rawgit.com/vipul-verma/LetsLearnAngular/master/index.html
Explanation:
A basic template.
Home link will load the partials/home.html.
About link will load the partials/about.html and partials/about-sublevel.html.
Problem:
Here partials/about-sublevel.html is a sub level of about page so it can be said its a part of about page or nested view/state of about page. But if you see the index page it has two views 'viewA' , 'viewB'.
'viewA' loads partials/home.html or partials/about.html according to link.
'viewB' loads only when About link is clicked with partials/about-sublevel.html.
Question:
Is there a way to separate the partials/about-sublevel.html page from index page and load inside about.html so I don't have to put the tag in index page as <div ui-view="viewB"></div>.
Correct way
'viewB' should load inside about.html since its a part of about page and when i click on about link both partials/about.html and partials/about-sublevel.html are displayed by default.
What is the correct way, Best practice in this scenario. What will be done in app.js to achieve this. Please give answer using the above git repo only and please. please don't give dummy answers without using the code from repo. Thank you
I think I don't understand your question completely, but the best practice would be to have 1 template for every state.
Here is an example of how I work with nested views:
var root = "/app/Views/";
$stateProvider
.state('/', {
url: '/',
templateUrl: root + 'Index.html'
})
.state('pas', {
url: '/pas',
templateUrl: root + 'Index.html'
})
.state('pas.calculate', {
url: '/calculate',
templateUrl: root + 'Calculate.html'
})
.state('pas.calculate.form', {
url: '/form',
templateUrl: root + 'Calculate/Form.html'
})
.state('pas.calculate.overview', {
url: '/overview',
templateUrl: root + 'Calculate/Overview.html'
})
.state('pas.contact', {
url: '/contact',
templateUrl: root + 'Contact.html'
})
$stateProvider
.state("otherwise", {
url: "*path",
templateUrl: root + "Index.html"
});

Angular ui router multiple named views for all states

I want to know if there is any way to write multiple named view for all states, the best example is when i want the nav bar and footer to appear in all routes.
$stateProvider
.state('home',{
views: {
'home': {
templateUrl: 'home.html',
controller: controller
},
'nav': {
templateUrl: 'nav.html',
controller:controller
},
'footer': {
templateUrl: 'footer.html',
controller: controller
},
}
})
I dont want to use ng-include, because the nav and the footer is showing before the home state is resolved in this case.
Yes you can, its actually written in the ui-router's guide on how to manage Multiple Named Views.
First, you need to define a specific set of named views in an abstract state, including the view where you would put all your content views such as your home.html and put it in a nameless view (empty string).
As you may have noticed, the demo below shows a root state named app, which is also an abstract state (this means you can't navigate in this state). It has three views, each represents a name that corresponds to the ui-views defined in the index.html.
Within the nameless view, contains the content.html that has a nameless ui-view that will represent all the child states of the app state. By doing this, you can share the nav.html and footer.html to all your states if you add these states under the app state. An example to this would be the app.home and app.items state. To learn more about this, read the link I've added above.
DEMO
Javascript
$urlRouterProvider.otherwise('/home');
$stateProvider.state('app', {
abstract: true,
views: {
nav: {
templateUrl: 'nav.html',
controller: 'NavController as Nav'
},
'': {
templateUrl: 'content.html',
controller: 'ContentController as Content'
},
footer: {
templateUrl: 'footer.html',
controller: 'FooterController as Footer'
}
}
})
.state('app.items', {
url: '/items',
templateUrl: 'items.html',
controller: 'ItemsController as Items'
})
.state('app.home', {
url: '/home',
templateUrl: 'home.html',
controller: 'HomeController as Home'
});
HTML
index.html
<ui-view name="nav"></ui-view>
<ui-view></ui-view>
<ui-view name="footer"></ui-view>
content.html
<hr>
<ui-view></ui-view>
<hr>
Depending on the rest of your routes you can probably make use of the abstract state to do this:
Angular UI Router - Views in an Inherited State might also help point you in the right direction.

Angular JS Routing - Links inside SPA

I have created a project with index.html with certain links to other pages. My routing works as intended but I'm wondering what's the best approach to go with when it comes to links on other pages.
To clarify it:
My index.html page has routes:
Feed
Bblog
Marketplace
Recruiting
Adverts
Now what I'm curious about is how do I for example route links inside these pages.
For example, my Bblog page has tabs which I want to be opened inside the same page. Now for example whenever I click some tab link, it redirects me to my index.html since my .otherwise route is set to /.
Not sure what engine or library you're using for your routing. Though I faced the same requirement not too long ago.
We're using ui-router for our routing. It's very similar to Angulars routing.
A snippet from our routing table contains something similar to this.
$stateProvider
.state('home', {
url: '/',
templateUrl: '/views/index',
})
.state('orders', {
url: '/orders',
templateUrl: '/views/orders',
})
.state('orderdetail', {
url: '/orders/detail/:id',
templateUrl: '/views/orderdetail',
})
.state('orderdetail.address', {
url: '/:addressId',
templateUrl: '/views/orderdetail',
})
Essentially you use the .dot notation to separate nested views. So the orderdetail.address is nested inside the orderdetail
This means that the routing above will go something allow you to see an overview of order details at /orders/detail/myOrderId and drill further in to, say, an address by visiting /orders/detail/myOrderId/myaddressId
If you're using ui-router then you will get more info on nested views on this link
If you're using angular ngRoute then the [ngRoute][3] docs and supporting plunker demonstrate how to stack up the routes.
So (from the plunker) -
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/Book/:bookId', {
templateUrl: 'book.html',
controller: 'BookController',
resolve: {
// I will cause a 1 second delay
delay: function($q, $timeout) {
var delay = $q.defer();
$timeout(delay.resolve, 1000);
return delay.promise;
}
}
})
.when('/Book/:bookId/ch/:chapterId', {
templateUrl: 'chapter.html',
controller: 'ChapterController'
});
this will give you /book/myBookId and /book/myBoodId/ch/myChapterId

Angular ui.router executing more than one state

I'm using AngularUI's router library and I have a strange issue: I have two distinct but similar states and controllers. What occurs is the state that I would expect runs, but then another state appears to run: it fetches the templateUrl and then the controller runs for the second state, which causes some weird behavior.
The states in question:
angular.module('app', ['ui.route'])
.config(function ($urlRouterProvider, $stateProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('list', {
url: "/",
templateUrl: STATIC_URL + "js/eleagemot/views/list.html",
controller: 'questionListCtrl',
})
.state('detail', {
url: '/{username:[a-zA-Z0-9\\-]+}/{slug:[a-z0-9\\-]+}/',
templateUrl: STATIC_URL + "js/eleagemot/views/detailed_question.html",
controller: 'questionDetailCtrl'
})
.state('newQuestion', {
url: '/new-question/',
templateUrl: STATIC_URL + "js/eleagemot/views/edit_question.html",
controller: 'editQuestion'
})
.state('questionEdit', {
url: '/{username:[a-zA-Z0-9\\-]+}/{slug:[a-z0-9\\-]+}/edit/',
templateUrl: STATIC_URL + "js/eleagemot/views/edit_question.html",
controller: 'editQuestion'
})
.state('answerEdit', {
url: '/answer/{id:[0-9]+}/edit/',
templateUrl: STATIC_URL + "js/eleagemot/views/edit_answer.html",
controller: "editAnswer"
})
});
Exactly what happens is if I go to /answer/1/edit/ it first loads the edit_answer.html template and runs the editAnswer controller, as it should. But then it also loads the edit_question.html template and runs the editQuestion controller. I know because there's some Restangular code that runs correctly in the editAnswer controller and then some similar Restangular code that runs in the editQuestion controller, but that causes a 404 and then the router redirects to the root. Also putting some console logs at the top of each controller shows that the editAnswer controller runs and then the editQuestion controller.
This behavior is only seen when loading the url for the answerEdit state, and not for any of the other states. Why is this happening and how can I fix it?
Looks like you've got some regular expressions that match too easily. Note that /answer/{id:[0-9]+}/edit/ always matches the above url pattern: '{username:[a-zA-Z0-9\\-]+}/{slug:[a-z0-9\\-]+}/edit/

Categories