How can I get the ui router in angular to resolve to the correct state?
I'm trying to run an angular application inside a subdirectory of my site but can't get the app.route.js to properly route the request. I set the "otherwise" directive to "dang" so that it's obvious to me if it misses.
I'm trying to reach the application at a URL like:
example.us/search
I'm landing at the proper directory in the url because I get routed to example.us/search/#!/dang
The file location for the content (ie app/partials/search.html) is a subfolder of the search folder, which is inside the root folder.
angular.module('example.usApp')
.config(function($stateProvider, $urlRouterProvider,$locationProvider) {
$urlRouterProvider.otherwise('dang');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/partials/search.html',
controller: 'searchController',
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
insertBefore: '#ng_load_plugins_before',
files: [
'app/services/searchService.js',
'app/controllers/searchController.js',
'css/home.css'
]
});
}]
}
})...
EDIT:
The files[] array above does not get loaded obviously because the url doesn't match. I'm having hard time loading any change because the browser thinks I'm trying to angular route and is not reloading the page at the URL I specify. When I type a change in the url bar and hit enter the URL is rewritten without making a request to the server.
EDIT2:
In answer to a question, yes oclazyload.js is loaded. From the developer tools you can see that all of the following are loaded in this order:
search/
bootstrap.min.css
style.css
angular.min.js
angular-ui-router.min.js
angular-local-storage.min.js
ocLazyLoad.min.js
angular-cookies.min.js
jquery.easing.1.3.js
angular-payments.min.js
app.js
app.constants.js
LoginService.js
app.route.js
bootstrap.min.js
app.constants.js
LoginService.js
app.route.js
bootstrap.min.js
This state is abstract so you will never hit it. I am assuming your main single page is Index.html right? If so change to this:
angular.module('example.usApp')
.config(function($stateProvider, $urlRouterProvider,$locationProvider) {
$urlRouterProvider.otherwise('dang');
$stateProvider
.state('home', {
url: '/search',
templateUrl: 'app/partials/search.html',
controller: 'searchController',
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
insertBefore: '#ng_load_plugins_before',
files: [
'app/services/HomeService.js',
'app/controllers/HomeMainController.js',
'css/home.css'
]
});
}]
}
})...
The url should be example.us/#/search.
Related
I have an angular config for loading routes.
app.config(["$stateProvider", "$urlRouterProvider",
function ($stateProvider, $urlRouterProvider) {
var states = [
{
name: "login",
config: {
url: "/login",
pageTitle: "Login",
template: "<login></login>"
}
},
{
name: "app",
config: {
url: "/app",
pageTitle: "Application",
template: "<app></app>"
}
}];
states.forEach(function (state) {
$stateProvider.state(state.name, state.config);
});
$urlRouterProvider.otherwise("/app/index");
}])
But I want to load states from server. So I need to use $http provider, but it does not work in config.
What will work for this scenario is not $http in .config(), but .run() and $urlRouterProvider.deferIntercept();. There is a documentation (link and small extract)
deferIntercept(defer)
Disables (or enables) deferring location change interception.
If you wish to customize the behavior of syncing the URL (for example,
if you wish to defer a transition but maintain the current URL), call
this method at configuration time. Then, at run time, call
$urlRouter.listen() after you have configured your own
$locationChangeSuccess event handler.
There are more details and working plunker https://stackoverflow.com/a/29013914/1679310
I have an app in Electron that works perfectly on windows, but when trying to run on mac, it wont load the first ui-view. Maybe this is a path issue cross os?
No errors on state change, console, or loading any files, but the ui-view is empty.
Folders:
app
- js
app.js (angular main)
- views
index.html
root.html
login.html
main.js (electron main)
Template:
<div ui-view="root"></div>
State:
$stateProvider
.state('app', {
abstract: true,
url: '/',
views: {
root: {
templateUrl: '../views/root.html',
},
}
})
.state('app.login', {
url: '',
views: {
content: {
templateUrl: '../views/login.html'
}
}
});
I was able to fix this by going from ui-router 0.2.15 to 0.2.18. Not exactly sure which bug was causing the issue.
I am trying to create a link in my template angularjs by doing something like:
<a ng-href="/#!/content/[[value.id]]">[[key]]</a>
But I am wondering myself if is possible do something like symfony2 does, example:
routing.yml
home_redirect:
path: /
defaults:
_controller: FrontendBundle:Controller:function
path: /home
permanent: true
options:
expose: true
And using it in your twig template by doing:
one link to home
That is really, really helpful because I don't have to "hardcode" all my routes.
To ensure a proper routing, you can use ui-router.
Here is an exemple on plunker
How this works :
1 - Follow the installation guide on their github
2 - Write your state definition :
app.config(function($stateProvider, $urlRouterProvider){
//If no route match, you'll go to /index
$urlRouterProvider.otherwise('/index');
//my index state
$stateProvider
.state('index', {
url: '/index',
templateUrl: 'index2.html',
controller: 'IndexCtrl'
})
//the variable state depending on an url element
.state('hello', {
//you will be able to get name with $stateParams.name
url: '/hello/:name',
templateUrl: 'hello.html',
controller: 'HelloCtrl'
})
});
3 - Write links by their state name :
//add this directive to an html element
//This will go to /index
ui-sref="index"
//This will go to /hello/
ui-sref="hello"
//This will go to /hello/ben
ui-sref="hello({name:'ben'})"
//This will go to /hello/{myname}
ui-sref="hello({name:myname})"
4 - Get the param into your controller :
//inject $stateParams
app.controller('HelloCtrl', function($scope, $stateParams){
$scope.controller = "IndexCtrl";
//get the param name like this
$scope.name = $stateParams.name;
});
Hope it helped. Also keep in mind the ui-router got some really powerful tools such as resolve and nested state/view. You'll probably need theses now or later.
PS : If the plunker don't work, just fork it and save again.
You could do this :
'use strict';
angular.module('AngularModule')
.config(function ($stateProvider) {
$stateProvider
.state('YourStateName', {
url: '/your/url',
views: {
'aViewName': {
templateUrl:'views/components/templates/yourTemplate.html',
controller: 'YourController'
}
},
resolve: {
}
});
});
// then in your controller
angular.module('AngularModule')
.controller('MyController',function($scope, $state){
$scope.goTo = function(){
$state.go('YourStateName');
}
}
);
//in your html make sure the <a> tag is in scope with the 'MyController'
<a ng-click='goTo'>[[key]]</a>
or
you can just do this :
<a ng-href="/your/url"></a>
that way you bypass the controller you can still put logic in the controller that was specified in the state
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
I use https://github.com/angular-ui/ui-router library. When I try to access index route ('/') I'm redirected to 404. The code:
angular.module('cr').config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: 'views/index.html'
});
$urlRouterProvider.otherwise('/404');
});
What's wrong with that code? Although when I use ui-sref="home" it works but the url looks like '/#/' but when a user inputs site name he uses just domain name, like 'mysite.com', not 'mysite.com/#/'
You've declared how to behave when any unknown/other route is provided - go to /404.
But we also have to define how to behave, when some expected, but not "exact" / "not known" route is accessed, ie. create alias
That's where the .when() could/should be used:
...
// the known route, with missing '/' - let's create alias
$urlRouterProvider.when('', '/');
// the unknown
$urlRouterProvider.otherwise('/404');
There is nothing wrong with your code. You are just missing an explicit state for 404. Try adding this:
.state('404', {
url: '{path:.*}',
templateUrl: 'views/404'
});
To get rid of the hash (#) symbol you need to inject one more dependency into your config module:
$locationProvider
And use the .html5Mode() method to set HTML5 Mode to true, like so
$locationProvider.html5Mode(true);
Also, ensure your server is configured to allow Angular to handle your routing. For example, here is a Node/Express configuration that allows the above technique to work:
app.get('*', routes.index);
And in your index.js file (or however you configure your node.js instance):
exports.index = function(req, res){
res.render('index');
};
Here by example:
// the known route, with missing '/' - let's create alias
$urlRouterProvider.when('', '/');
// Redirect any unmatched url to 404 view (without change location.hash)
$urlRouterProvider.otherwise(function($injector) {
var $state = $injector.get('$state');
$state.go('404', null, {
location: false
});
});
$stateProvider
// homepage views
.state('homepage', {
url: "/",
templateUrl: "views/homepage.html",
data: {
pageTitle: 'Home'
}
... more here ...
})
// 404 views
.state('404', {
url: "/404",
templateUrl: "views/404.html",
data: {
pageTitle: '404 Not found'
}
});
The simplest way for me with ui-router was giving the url field an empty value :
$stateProvider
.state('home', {
url: '',
templateUrl: 'views/homepage.html',
controller: 'AppCtrl'
})