I'm trying calling the /auth/logout url to get redirected after session is deleted:
app.config(['$routeProvider',function($routeProvider) {
$routeProvider
.when('/auth/logout',{
controller:'AuthLogout'
//templateUrl: not needed
})
})
.controller('AuthLogout', ['$window','$location', function ($window,$location) {
$window.localStorage.removeItem('user_username');
$window.localStorage.removeItem('user_id');
$window.localStorage.removeItem('user_session_token');
$location.path('/');
}]);
I actually don't need a view for AuthLogout controller but if I do not specify the templateUrl in routeProvider I can't get this to work, while if I specify a templateUrl it works.
How can I call the url/controller without to having to load a view??
You could do :
.when('/auth/logout', {
controller: function(){
//do staff
}
})
btw may be there is something wrong in your code
because template works and you could exploit it in
the same way
http://docs.angularjs.org/api/ngRoute/provider/$routeProvider
You can use a resolve handler according to the post https://github.com/angular/angular.js/issues/1838
Checkout this quick example and notice the alert statement in resolve.
http://jsfiddle.net/Wk7WD/34/
.when('/detail/:id/', {
resolve: {
load: function ($route, dataService) {
alert("hello");
//Your statements instead of all this which I found in an example
return dataService.load($route.current.params.id);
}
}
})
Instead of the alert you can have your own statements
use redirectTo
app.config(['$routeProvider',function($routeProvider) {
$routeProvider
.when('/auth/logout',{
redirectTo:'/'
})
});
Hope this will work for you :)
Related
I have this problem & I am unable to find the solution for it.
This is an example of code where I am trying to route to variable URL routing
$routeProvider.when('/Book', {
template: 'examples/book.html',
controller: BookCntl,
});
$routeProvider.when('/Book/chapter01', {
template: 'examples/chapter01.html',
controller: ChapterCntl,
});
If I want to fix the url till /Book/chapter and 01 can be a variable. Like if user changes 02 or 03 till 100. Do I need to write the $routeProvider 100 times or can be a simple solution, where I can use the number part as a variable and write single $routeProvider to handle 01 to 100?
No, you do not need to add 100 seperate route definitions. You add a variable to your url template by adding /:some_variable, and then you are to fetch that variable by using the $routeParams service.
Example
$routeProvider.when('/Book/chapter/:chapterid', {
templateUrl: 'examples/chapter-view.html',
controller: ChapterCntl,
});
And then inject $routeParams into your controller:
function ChapterCntl($routeParams) {
var chapterId = $routeParams.chapterid;
//use the id to fetch content.
}
It does seem like you have a different html page for each chapter. If that is the case you can set a function to the template field to generate the path for the html file:
$routeProvider.when('/Book/chapter/:chapterid', {
template: function(routeParams) {
var id = routeParams.id;
return 'examples/chapter'+id+'.html';
},
controller: ChapterCntl,
});
If that case is that you are fetching the data from an API through a service, it might be useful to be using the resolve field instead. The resolve field will loaded the data and be injectable into the controller. Which means that the data will be loaded before transitioning in to the new route.
$routeProvider.when('/Book/chapter/:chapterid', {
templateUrl: 'examples/chapter-view.html',
controller: ChapterCntl,
//Will run the below function before transitioning into new route.
resolve: {
chapter: function($routeParams, chaptersDataService) {
var id = $routeParams.chapterid;
return chaptersDataService.getChapter(id);
}
}
});
And the inject the chapter into your controller:
function ChapterCntl($scope, chapter) {
$scope.chapter = chapter;
console.log( chapter );
}
Have you considered UI Route Provider? You could easily use stateparams..
$stateProvider
.state('book.chapter', {
url: "/book/chapter/:chapterId",
templateUrl: 'book.chapter.detail.html',
controller: function ($stateParams) {
....
}
})
Sources:
https://github.com/angular-ui/ui-router/wiki/url-routing#url-parameters
http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider
You could also stick with routeprovider in a slightly different way than suggested in other answers.
$routeProvider.when('/Book/:chapter', {
templateUrl : { function (dynamicUrl) {
return '/Book/' + dynamicUrl.chapter + '.html';
},
controller: 'ChapterCntl'
});
Lets say I have a an angular ui router route set up. When I change to that state, I'm telling Angular that I want it to resolve a factory call first then load the view. But what happens when that api call is empty? I would like to inform the user that there was no results found and stay on at my original state. Not transition to another view with no data to display. What is the best way to achieve this?
The route (which works as expected so far when I know there will be a return)
'use strict';
angular.module('testApp')
.config(function ($stateProvider) {
$stateProvider
.state('spinnerTest', {
url: '/spinner_test',
templateUrl: 'app/spinnerTest/spinnerTest.html',
controller: 'SpinnerTestCtrl',
resolve: {
names: function(NamesService){
//What happens if I return an empty array []?
//How do I return to the previous state?
NamesService.getNames();
}
}
});
});
You can simply reject promise in resolve in case of empty array:
resolve: {
names: function(NamesService) {
return NamesService.getNames().then(function(names) {
return names.length == 0 ? $q.reject('no names') : names;
});
}
}
This is a cross cutting concern, it is probably not unique to the Name service, but other services you are using as well.
Since you didn't post the code to the Name service (NameService service is redundant) I will assume it uses either the $http or $resource service. You can then use a $httpInterceptor that will trigger the display of a message to the user that "The selection is unavailable at this time".
You could call $state.go in your resolve, if you'd like
'use strict';
angular.module('testApp')
.config(function ($stateProvider) {
$stateProvider
.state('spinnerTest', {
url: '/spinner_test',
templateUrl: 'app/spinnerTest/spinnerTest.html',
controller: 'SpinnerTestCtrl',
resolve: {
names: function(NamesService, $state){
//What happens if I return an empty array []?
//How do I return to the previous state?
return NamesService.getNames().then(function(names){
if (!names.length) {
return $state.go('otherState');
}
return names;
});
}
}
});
});
I am using AngularJS and ui-router and in my app.js. I have the following line:
$urlRouterProvider.otherwise('/');
However I do not want it to send the user to a URL but instead to a state:
.state('404',
{
views: {
'body': {
templateUrl: 'partials/404.html',
}
}
});
Normally I would just do this:
$state.go('404');
How can I do this for the otherwise method?
Note: that my 404 state does not have a URL, so basically it keeps the URL that the user has entered or visited and just changes the template.
I think you achieved that with this code
$urlRouterProvider.otherwise(function($injector, $location){
$injector.invoke(['$state', function($state) {
$state.go('404');
}]);
});
Try This.
$urlRouterProvider.otherwise(function($injector, $location){
$injector.get('$state').go('404');
});
Just a small improvement to #kdlcruz's answer:
$urlRouterProvider.otherwise(function($injector){
$injector.invoke(['$state', function($state) {
$state.go('404', {}, { location: false } );
}]);
});
By doing that, you still able to keep the incorrect the URL and only state is changed.
I am developing an application with angularjs what I need to do is to basically run some scripts when route is changed to a specific route I know that I can define a separate controller for each route. since, some routs are supposed to have shared data I shared a controller to between some of them
formApp.config(function($routeProvider) {
$routeProvider
.when('/firstUrl',{
templateUrl : 'firstURL',
controller : 'mainController'
})
.when('/secondURL' , {
templateUrl : 'secondURL',
controller : 'mainController'
})
}).run(function($rootScope, $location) {
$rootScope.$on("$routeChangeStart", function(event, next, current) {
if ( signed_in == false ) {
$location.path("/login");
}
});
});
The above is my config code,
MY QUESTION : I need to know if I can modify the code in the run() function, so that based on the route which user is redirected to some scripts are run.
or if this is not the right way to do that please correct me how do I have to solve this issue?
thanks in advance
I would recommend to create at least one controller per route. It makes the code more manageble.
Then you can define an init function that runs when each controller loads.
To share data between controllers you need to create a service, which is the correct way to do it rather then sharing the same controller for multiple paths.
It will also give you way more flexibilitywhen developing.
Update
Example
( Naming for example purposes only. Try to never do arrbitrary naming. )
#Service
angular.module('myService', [])
.factory('mSrv',[ function() {
return {
data: {
'first_name': 'John',
'last_name': 'Doe'
}
};
}])
;
#Controller1
angular.module('initMyCtrl1', ['myService'])
.controller('InitMyCtrl1', function( $scope, mSrv ) {
var initMyCtrl1 = function(){
console.log('runs on controller load')
console.log(mSrv.data);
};
initMyCtrl1();
})
;
#Controller2
angular.module('initMyCtrl2', ['myService'])
.controller('InitMyCtrl2', function( $scope, mSrv ) {
var initMyCtrl2 = function(){
console.log('runs on controller load')
console.log(mSrv.data);
};
initMyCtrl2();
})
;
I'm having trouble figuring out how to get the routeProvider to wait until a remote call returns. The best solution I've seen for far was the example here: delaying angular route change
. Unfortunately, when I tired to apply that example to my own code, the binding would trigger before the data was actually loaded. Does anyone know of another example that uses the new Resource syntax from angular 1.1.5 ($promise can be accessed directly )?
Here is what my code looks like:
var productModule = angular.module('productModule', ['ngResource', 'ngLocale']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html',
controller: 'ResourceCtrl as appController' ,
resolve:
{
productData: function($resource)
{
console.log(["calling service"]);
return $resource(Services.ProductServices.PATH).query(null,
function(data){
console.log(["call succeeded"]);
},
function(data){
console.log(["calling failed"]);
}).$promise;
}
}
});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html'});
$routeProvider.otherwise({redirectTo: '/view1'});
}]) ;
productModule.controller('ResourceCtrl','$scope','productData',function($scope,productData) {
$scope.productData = productData;
console.log(["promise resolved"]);
}]);
If I run that code, the console would display:
calling service
promise resolved
call succeeded
It should be as simple as this:
resolve: {
productData: function(ProductServices) {
return ProductServices.query().$promise.then(function(data){
return data;
});
}
}
If your Service looks something like this:
myApp.factory('ProductServices', function($resource) {
return $resource('/path/to/resource/:id', { id: '#id' });
});