I have this app.js file
angular.module('myApp', [
'myApp.version',
'ui.router'
]).
config(['$locationProvider','$urlRouterProvider','$stateProvider', function($locationProvider,$stateProvider, $urlRouterProvider, $httpProvider) {
$urlRouterProvider.otherwise('/view1');
$stateProvider
.state('view1', {
url: '/view1',
templateUrl: 'partials/view1.html'
//controller: 'view1.MainController'
})
.state('view2', {
url: '/view2',
templateUrl: 'partials/view2.html'
})
.state('view3', {
url: '/view3',
templateUrl: 'partials/view3.html'
})
.state('view4', {
url: '/view4',
templateUrl: 'partials/view4.html'
});
}]);
I have included "https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.min.js" CDN in my index.html file and it is getting loaded fine.
But even when it is loaded the console is giving an error as
Failed to instantiate module myApp due to:
TypeError: $urlRouterProvider.otherwise is not a function
I tried removing this line and then test the code, but then it gives
Failed to instantiate module myApp due to:
TypeError: $stateProvider.state is not a function
I have gone through the code multiple times but I am unable to identify the mistake/error.
(angular version is 1.5.8 and angular-ui-router version is 0.3.1 ,if that helps)
Please Help!
You inverted the parameters: urlRouterProvider and stateProvider.
wrong order:
config(['$locationProvider', '$stateProvider', '$urlRouterProvider', function($locationProvider, $urlRouterProvider,$stateProvider, $httpProvider) {
right order:
config(['$locationProvider','$urlRouterProvider','$stateProvider', function($locationProvider, $urlRouterProvider,$stateProvider, $httpProvider) {
You used that technique to avoid problems with minification, but the order of the "stringed-names" must be the same to the order of the function parameters.
I bet you know that and just mistyped.
Related
If a user types myURL/ or myURL/#/ or even myURL/#/foo they get to my index page.
But if they type myURL/foo, they get a 404. This is terrible. They should instead be redirected to /.
I am trying to implement this and am not having a lot of luck.
(function() {
'use strict';
angular
.module('myApp')
.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('index', {
name: 'index',
url: '/',
templateUrl: 'js/views/page1.html',
controllerAs: 'page1Controller',
data: { pageTitle: 'Main' }
})
.state('page2', {
name:'page2',
url: '/page2/:id',
templateUrl: 'js/views/page2.html',
controllerAs: 'page2Controller',
data: { pageTitle: 'page2' }
})
$urlRouterProvider.otherwise('/');
}]);
})();
I have looked at dozens of articles, and nowhere do I seem to be able find this simple case handled.
On the official docs it is mentioned that you can pass $injector and $location to the function otherwise.
Their example looks like this:
app.config(function($urlRouterProvider){
// if the path doesn't match any of the urls you configured
// otherwise will take care of routing the user to the specified url
$urlRouterProvider.otherwise('/index');
// Example of using function rule as param
$urlRouterProvider.otherwise(function($injector, $location){
... some advanced code...
});
})
What you can do to achieve your goal is to create a state, and whenever something it's not matched and enters otherwise fct, send it to that state.
$urlRouterProvider.otherwise(function($injector, $location){
$injector.get('$state').go('404');
});
I have not tested this but should work.
I have been able to switch out my angular router code with ui-router and it works fine with a basic setup. But on my page I have a partial that I want to reuse in multiple views and I can't get that working. Can anyone see an issue with my code below.
routes....
$stateProvider
.state( 'jobs', {
url: '/jobs',
templateUrl: templates.jobs,
views: {
'jobs': {
templateUrl: templates.jobList,
controller: 'JobListController'
},
'alert': {
templateUrl: templates.alert,
controller: 'AlertController'
}
}
})
templates.jobs file...
<div ui-view="jobs"></div>
<div ui-view="alert"></div>
and then the templates.jobList and templates.alert are just regular html blocks.
I have a main page with just a where my app initially loads. It's within this ui-view that I want to load the templates.jobs view along with it's nested views.
I've found that if I remove the templateUrl: templates.jobs from my jobs state and then move the two ui-views from that jobs file to my main html file it works. However, my main file needs to be able to load many potential views - the ui-view on the main html is just a placeholder where the rest of the application lives. So I can't have those two ui-views in my main file. Is there a way to make this work? Thanks.
Also set the parent view of jobs state in the views object and use absolute targeting:
$stateProvider.state('jobs', {
url: '/jobs',
views: {
'#': {
template: '<div ui-view="jobs"></div><div ui-view="alert"></div>',
controller: function () {}
},
'jobs#jobs': {
template: '<h2>Joblist</h2>',
controller: function () {}
},
'alert#jobs': {
template: '<h2>alert</h2>',
controller: function () {}
}
}
});
Working example on Plunker: http://plnkr.co/edit/AR8RK1Ik1xeGL0xUBV6e?p=preview
Reference: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views#view-names---relative-vs-absolute-names
I have an ember app that I am developing and everything is working fine except when I refresh the page whilst on a nested route eg. /projects/1 I receive the following error:
Assertion Failed: You may not passundefinedas id to the store's find method
I am fairly sure this is to do with the way I have setup my routing but can't seem to reorganise them to fix it.
They look like so:
App.Router.reopen({
location: 'auto',
rootURL: '/'
});
App.Router.map(function() {
this.route('projects', { path: '/'});
this.route('project', { path: '/projects/:id' });
});
Any help would be awesome! Thanks.
My first suggestion for you would be to change :id segment do :project_id - it's how they define it in documentation. So your router code looks like:
App.Router.map(function() {
this.route('projects', { path: '/'});
this.route('project', { path: '/projects/:project_id' });
});
If this doesn't help, create:
App.ProjectRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('project', params.project_id);
},
});
If you still get error with passing undefined to store.find try to console.log(params) and see if project_id is defined there and matches value from URL.
$state.go isn't transitioning to default.settings.customization but instead its going to our 'main frontpage' default.feed
I think it has to do with the resolve, since when I change var state to a different state, it works just fine.
app.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('default.settings.customization', {
url: '/settings/customization',
templateUrl: 'app/settings/customization/customization.html',
controller: 'CustomizationCtrl',
auth: {
authorizedRoles: ['admin']
},
resolve: {
customization: [
'CustomizationService',
function(CustomizationService) {
return CustomizationService.get().then(function(res) {
return res.data;
});
}
]
}
});
}]);
Test:
var state = 'default.settings.customization';
it('should resolve data', function() {
customizationServiceMock.get = jasmine.createSpy('customizationServiceMockGet')
.and.returnValue(apiResp.accountCustomization);
$state.go(state);
$rootScope.$apply();
expect($state.current.name).toBe(state);
});
LOG:
PhantomJS 1.9.8 (Linux) app/settings/customization router should resolve data FAILED
Expected 'default.feed' to be 'default.settings.customization'.
Error: Expected 'default.feed' to be 'default.settings.customization'.
I think it's related to your spy function, check that apiResp is available in your scope. I had a similary problem, I used $q to return a promise in my spy function but $q was not injected.
I'm trying to make some nested states with dynamic options.
This kind of states works fine: app, app.process, app.process.step2
But my situation is little different because I want to pass some data in URL.
Here is my states
.state('app.process/:type', {
url: "/process/:type",
views: {
'menuContent1': {
templateUrl: "templates/intro.html",
controller: 'IntroCtrl',
}
}
})
.state('step/:type/:step', {
url: "/process/:type/:step",
parent: 'app.process',
views: {
'proiew': {
templateUrl: "templates/processes/increase.html",
controller: "increaseCtrl",
}
}
})
While trying to run this
$state.go('step/:type/:step', {type:$stateParams.type, step:2});
I get an error
Error: Could not resolve 'new/:type/:step' from state 'app.process/:type'
at Object.transitionTo (http://localhost:8100/lib/ionic/js/ionic.bundle.js:33979:39)
at Object.go (http://localhost:8100/lib/ionic/js/ionic.bundle.js:33862:19)
at Scope.$scope.goNext (http://localhost:8100/js/controllers/IntroCtrl.js:11:18)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:18471:21
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:43026:9
at Scope.$eval (http://localhost:8100/lib/ionic/js/ionic.bundle.js:20326:28)
at Scope.$apply (http://localhost:8100/lib/ionic/js/ionic.bundle.js:20424:23)
at HTMLButtonElement.<anonymous> (http://localhost:8100/lib/ionic/js/ionic.bundle.js:43025:13)
at http://localhost:8100/lib/ionic/js/ionic.bundle.js:10478:10
at forEach (http://localhost:8100/lib/ionic/js/ionic.bundle.js:7950:18)
any suggestions?
there are many different ways to pass parameters to a state, first of all you can simply set the parameters on the click of the link and then take them from the scope.
but if we are talking on something more reliable and readable i suggest this post, and specifically i like using Resolve. i'll put here an example of resolve, but i encourage you to read and find out what works best for you:
$stateProvider
.state("customers", {
url : "/customers",
templateUrl: 'customers.html',
resolve: {
// A string value resolves to a service
customersResource: 'customersResource',
// A function value resolves to the return
// value of the function
customers: function(customersResource){
return customersResource.query();
}
},
controller : 'customersCtrl'
});