I have looked at the other solutions. They basically state that you should be sure to include a call to the x.state.js file from the index.html file. I have that.
When I change the name of the state the error gets updated. So if I had a state called "mystate" and called it from a button's ui-sref it would say "Could not resolve 'mystate' from state 'home'. If I changed the ui-sref and the state name to "yourstate" the error message changes to "Could not resolve 'yourstate' from state 'home'. So I don't know where else to look.
Update with some code that I really just took from a website tutorial to test this out but here goes:
myupload.state.js
'use strict';
angular.module('myApp')
.config(function ($stateProvider){
$stateProvider
.state('upload',{
parent: 'home',
url: 'upload',
data: {
roles: [],
pageTitle: 'Upload Your Files',
displayName: 'Upload Your Files'
},
views: {
'content#': {
templateURL: 'my/path/myupload/upload.html',
controller: 'UploadController'
}
},
resolve: {}
})
}
);
There is a upload.directive.js file in the same directory. A uploadcontroller.js file in that same directory. And a upload.html file.
In the 'home' page HTML file I have a button with the following syntax. When clicked it is supposed to route you to the above page for a file upload.
<button class='btn' ui-sref='upload()'>
There are no other errors to troubleshoot with.
I have a couple of other states to look at and this one looks just like those.
Those buttons/states work.
Where else should I be looking?
My problem turned out to be needed security code specific to the application I am working on (inherited) in the resolve: section of the state clause. Once I added that the button worked just fine.
Related
I have done some research but couldn't find a definitive answer. I have main application area where I load different screens. From one screen I want to open a page that would cover the whole screen. So, navigating to 'viewreport' does exactly that. And when I click on Browser's Back button or have my own Back button on the whole screen page I want to get back to the previous state without reloading its template and controller. Another words, I want to see all selections I have done prior opening the whole screen page. Here is my state configuration:
$stateProvider
.state('body', {
url: '/',
abstract: true,
template: '<div ui-view />'
})
.state('viewreport', {
url: 'viewreport',
templateUrl: 'wholescreen.html',
controller: 'wholescreenController'
});
I am loading different modules into the main 'body' state which might look like this:
function ($stateProvider) {
$stateProvider.state('body.htmlreports', {
templateUrl: function ($stateParams) {
return 'htmlReports.html';
},
controller: 'htmlReportsController',
url: 'htmlreports',
}).state('body.htmlreports.reportarea', {
templateUrl: 'htmlReportParams.html',
controller: 'htmlReportParamsController',
});
I am navigating to viewreport state from htmlReportParamsController controler. The new page then opens into the whole screen. That part works fine. But navigating back to htmlreports when clicking on the Browser's Back button will reload 'body.htmlreports' state. Is there a way of getting back to it without reloading its template?
Update. Why I think it's not a duplicate.
I tried what's suggested in it before posting. This: $state.transitionTo('yourState', params, {notify: false});
still reloads 'yourState'. Also the use case in the provided link is not exactly as mine. Because the OP uses edit mode for already loaded view while I am loading a new view over the the whole screen.
Thanks
Use
$window.history.back();
Add $window in dependency injections of your controller. This will refresh your page and wont reload data we selected.
Please maintain states like this
function ($stateProvider) {
$stateProvider.state('body.htmlreports', {
templateUrl: function ($stateParams) {
return 'htmlReports.html';
},
controller: 'htmlReportsController',
url: 'htmlreports',
}).state('body.htmlreports.reportarea', {
templateUrl: 'htmlReportParams.html',
controller: 'htmlReportParamsController',
}).state('body.htmlreports.reportarea.viewreport', {
url: 'viewreport'
});
This is my menu Transaksi > Sewa there is konfirmasi button which should load new page which contain form input and submit button on clicked.
My application in local language so to make it simple, it's rent car application, at sewa page there is list of rent car transaction, but not yet confirmed the payment. so the konfirmasi button take care of this.
If user click the konfirmasi button it will load some info based on transaction id (route params) and there is file input to upload payment proof from bank transfer and some submit button to upload to image to server and to update database status for current transaction.
I follow official documentation create to create Sewa page so My directory structure is something like app/pages/transaksi/transaksi.module.js, app/pages/transaksi/sewa/sewa.module.js
Here is transaksi.module.js code
(function () {
'use strict';
angular.module('BlurAdmin.pages.transaksi', [
'BlurAdmin.pages.transaksi.sewa'
])
.config(routeConfig)
function routeConfig($stateProvider){
$stateProvider
.state('transaksi', {
url: '/transaksi',
template: '<ui-view></ui-view>',
abstract: true,
//templateUrl: 'app/pages/transaksi/transaksi.html',
//controller: 'TransaksiCtrl',
title: 'Transaksi',
sidebarMeta: {
icon: 'ion-grid',
order: 100
}
});
}
})();
Here is sewa.module.js
(function () {
'use strict';
angular.module('BlurAdmin.pages.transaksi.sewa', [])
.config(routeConfig);
function routeConfig($stateProvider){
$stateProvider
.state('transaksi.sewa', {
url: '/sewa',
templateUrl: 'app/pages/transaksi/sewa/sewa.html',
controller: 'SewaCtrl', //listing work normally
title: 'Sewa',
sidebarMeta: {
order: 0
}
})
.state('transaksi.sewa.konfirmasi', {
url: '/konfirmasi/:nomor_order_sewa',
templateUrl: 'app/pages/transaksi/sewa/konfirmasi.html', //won't load
controller: 'KonfirmasiCtrl',
title: 'Konfirmasi Sewa', //but title is changed
sidebarMeta: {
order: 0
}
});
}
})();
The controller loaded in app/pages/transaksi/sewa/sewaCtrl.js something like this
(function (){
'use strict';
angular.module('BlurAdmin.pages.transaksi.sewa')
.controller('SewaCtrl', SewaCtrl)
.controller('ModalCtrl', ModalCtrl)
.controller('KonfirmasiCtrl', KonfirmasiCtrl);
function KonfirmasiCtrl($scope, $http, $routeParams){
$scope.nomor_order = $routeParams.nomor_order_sewa;
alert($scope.nomor_order);
}
...
...
There is no error in console, and my templateUrl konfirmasi.html is exist and contain something simple as
<h1>ini halaman konfirmasi untuk order {{ nomor_order }}</h1>
So why when I click konfirmasi button the pages change only the tittle but templateUrl not loaded.
Maybe I have been doing wrong in sewa.module.js at konfirmasi route definition? or somewhere?
If you need more detailed please just comment.
Jus't reading angular ui router nested views not working and read nested state abstrac usage exactly at this section
// Note: abstract still needs a ui-view for its children to populate.
// You can simply add it inline here.
and I'm start thinking maybe the page won't load because no container so with a little bit try and error.
I discover that I need to add <div ui-view></div> at sewa.html so now sewa.html looks like
<div ui-view>
...
sewa.html content here
...
</div>
Thanks stackoverflow.
Edit: Here is the complete code at Plunker. Though I can not c anything in execution but same code working at local. However gives a console error though
It all works perfect. But due to :id in /news/:id/, i am getting jquery/angular errors in console which can not be tracked anywhere in my code
I can not c What i am doing wrong.
Edit: Solved plunker https://plnkr.co/edit/FWcuBgGpVdMj3CroFrYJ
First of all you are trying to use ui-router but you're including ngRoute script in your plunker. Change it to
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.min.js"></script>
Then everything should work fine!
I suggest you a few changes...
1. Use ui-sref instead of href because it's much easier to define
ui-sref="post({id:1})" which turns into href="#/news/1"
If you would like to change url some day, then you will have to just change your route file, not each href.
$stateProvider
.state('post', {
url: "news/:id"
or
$stateProvider
.state('post', {
url: "archive/:id"
or
$stateProvider
.state('post', {
url: "whatever/:id"
2. Use abstract state
In your example it's a way better to define abstract state which holds header, content and footer - it's a typical use case.
ui-router
Abstract States
An abstract state can have child states but can not get activated
itself. An 'abstract' state is simply a state that can't be
transitioned to. It is activated implicitly when one of its
descendants are activated.
Some examples of how you might use an abstract state are:
To prepend a url to all child state urls. To insert a template with
its own ui-view(s) that its child states will populate. Optionally
assign a controller to the template. The controller must pair to a
template. Additionally, inherit $scope objects down to children, just
understand that this happens via the view hierarchy, not the state
hierarchy. To provide resolved dependencies via resolve for use by
child states. To provide inherited custom data via data for use by
child states or an event listener. To run an onEnter or onExit
function that may modify the application in someway. Any combination
of the above. Remember: Abstract states still need their own
for their children to plug into. So if you are using an
abstract state just to prepend a url, set resolves/data, or run an
onEnter/Exit function, then you'll additionally need to set template:
"".
Here's a plunker which shows how I would do it.
https://plnkr.co/edit/5FvJaelyxdl5MuALt5VY?p=preview
Hope it helps.
Look at the documentation for ui router named views,
You can use following syntax for using multiple views
$stateProvider
.state('state',{
url: '',
views: {
'header': {
templateUrl: 'views/header.html',
controller: 'headerCtrl'
},
'content': {
template: '<div ui-view=" "></div>', //<-- child templates loaded to here
},
'footer': {
templateUrl: 'views/footer.html',
controller: 'footerCtrl'
}
}
})
.state('state.post', {
url: 'news/:id/:KeyWords'
templateUrl: 'views/post.html' //<-- This goes into content's ui-view
});
I'm guessing you want to keep the header and footer and change content views.
You can achieve this by making this state as parent to all other states
suppose
.state('main',{
abstract: true,
views: {
'header': ... ,
'content': {
template: '<ui-view></ui-view>',
}
'footer': ...
}
})
then all the child views will load their views in the ,
ex: in main.child etc, your template will load in the content's <ui-view></ui-view> tag
If you need to use a custom template depending on keywords you can do the following:
.config(['$routeProvider',
function($routeProvider, $routeParams) {
$routeProvider
.when('/news/:id/:keyWords', {
template: '<div ng-include="url"></div>',
controller: "exampleController"
})
then in the exampleController
function($routeParams, $scope) {
$scope.url = $routeParams.keyWords;
}
I am building a simple HTML site using Angular JS ui-router.
I have built a custom 404 page ('www.mysite/#/error/404'), to which the user is redirected if the user types a url like 'www.mysite/#/invalidUrl'. This functionality was achieved by the following code snippet:
$urlRouterProvider
.when('', '/')
.when('/home', '/')
.otherwise('/error/404');
And the following state snippet:
$stateProvider.state('404', {
parent: 'app',
url: '^/error/404',
views: {
'errorContent#main': {
controller: 'error404Controller',
templateUrl: 'js/general/templates/error404.html'
}
}
});
I am trying to capture the invalid URL requested by the user to be displayed to the user like below.
The URL you requested cannot be found
Request: www.mysite.com/#/invalidUrl
I have tried listening to '$stateNotFound' event, which only seems to be firing when a specific invalid state is requested. I've also tried to listening to events '$stateChangeStart', '$locationChangeStart', and '$locationChangeSuccess' but couldn't find a way to achieve this functionality.
Is this possible? Please, share your thoughts - thank you
Awesome! Thank you Radim Köhler. I don't know how I didn't land on that thread when I searched but that helped me get the answer.
I changed the answer in that thread to fit my scenario which I am going to leave below for reference to any other users.
$stateProvider.state('404', {
parent: 'app',
url: '^/error/404',
views: {
'errorContent#main': {
controller: 'error404Controller',
templateUrl: 'js/general/templates/error404.html'
}
}
});
$urlRouterProvider
.when('', '/')
.when('/home', '/')
.otherwise(function ($injector, $location) {
var state = $injector.get('$state');
state.go('404', { url: $location.path() }, { location: true });
});
So the magic change was the function defined for 'otherwise' option. I didn't change the URL of the 'error' state. Instead, I used the 'state.go' to activate state '404' and passed the location path as the state parameter.
Setting location=true will take you to the URL of the state, and location=false will not. Whichever way you prefer the invalid URL can be accessed easily now.
I have a function like this, supposed to load some routes.
.config(function($stateProvider, $urlRouterProvider){
$stateProvider.state('app', {
abstract: true,
templateUrl: "index.html",
})
$stateProvider.state('index', {
url: '/',
views: { "index" : { templateUrl: "index.html" } },
parent: "app",
});
$stateProvider.state('register', {
url: "/register",
views: { "register" : { templateUrl: "templates/register.html", } },
parent: "app",
});
$urlRouterProvider.otherwise("/");
})
But i am getting
Error: Could not resolve 'register' from state ''
exception. From all other examples i checked, that route config look fine. But it's not working some reason.
I suspect that my routes are not loaded, i put console.log, debugger and alert functions inside my .config function but none of them are executed.
Is there any way to list all loaded routes from ui-router?
Disclaimer: I would like to give you a hint. If this answer would not suite, let me know, will delete that. Because obviously, my previous answser is not working for you: Could not resolve '...' from state ''
What could be the source of the error message like this?
Could not resolve 'register' from state ''
There are only two options.
File with the state definition is not loaded. (Could be checked with some console.log stuff)
File represents module which is properly loaded, but not referenced by the root ng-app="myApp"
I would strongly expect, that the second case is the issue. Here is a BROKEN example, which will (after button click) show the error: Could not resolve 'register' from state ''
What happened. There is a file called "otherStates.js", which is loaded into index.html
...
// see the scripts loaded above
// below is the root module name "myApp"
...
The "otherStates.js" declares module "myStates", which contains all the states:
// will always be in a console
// because file is loaded
console.log("file is accessed");
angular
.module('myStates', ['ionic'])
.config(function($stateProvider, $urlRouterProvider){
// never reach console, because this module is not used
console.log("module myStates is not referenced in myApp ");
console.log("these lines will never be trigerred");
$stateProvider
.state('app', {
abstract: true,
...
})
....
So Why we do get that error? How to fix that?
Simply, in script.js, (where is our root module) we have this declaration:
var app = angular.module('myApp', ['ionic'])
And that is not enough. We need to also reference the myStates. So we must change it like this and all will work
var app = angular.module('myApp', ['ionic', 'myStates'])
Check this broken example