$location.path or $location.url doesn't trigger the ngRoute controller - angularjs

I have a route defines as follows:
$routeProvider.
when('/projects/', {
controller: 'ProjectCtrl',
controllerAs: 'project_ctrl',
templateUrl: '/static/app/partials/project.html'
}).
After the login finishes I need the user to land on this link, hence in my controller I am using this:
vm.login = function(form) {
if (form.$valid) {
loginService.login(vm.loginFormData.username, vm.loginFormData.password);
loginService.setUpUser()
$location.url("/projects");
}
}
But unfortunately the controller associated with this view is not triggered, that is ProjectCtrl is not triggered. However when I click on the navigation link which uses in the dom, it works fine. Can someone please guide me here, may I am missing something conceptual.
Hence the larger question is how do I redirect a user in the controller using some APIs which also complies with ngRoute based controllers.

Try removing the last / in url so it matches $location.url("/projects");
$routeProvider.
when('/projects', {

Related

Providing variables outside of ng-view

So, I have an HTML page, /profile#IDGoesHere which is tied an an ng-app. The ng-app has three columns (with Bootstrap) and the middle of which is utilising Angular's ng-view.
So it's something like this:
/profile#IDGoesHere (and within it):
All Activity
Posts
Likes
Dislikes
etc
The href links are set on the HTML page outside of the ng-view so when I go into the /profile#IDGoesHere page, I set the userID into a variable using a service. Like below:
profileApp.service('globalParams', function() {
var profileID = '';
var user = {};
return {
getProfileID: function() {
return profileID;
},
setProfileID: function(value) {
profileID = value;
}
};
});
I pass the 'globalParams' service into each controller as I need to access the profileID in order to make further calls to get the specific data for the user.
My Angular Router looks like this:
$routeProvider
.when('/profile:id', {
templateUrl : 'partial/profile/feed.html',
controller : 'mainController',
resolve:{
myData: ['$http', function($http){
return $http.get('/session');
}]
}
})
.when('/posts', {templateUrl: 'partial/profile/posts.html', controller: 'postsController'})
.when('/agreed', {templateUrl: 'partial/profile/likes.html', controller: 'likesController'})
.when('/disagreed', {templateUrl: 'partial/profile/dislikes.html', controller: 'dislikesController'})
.when('/comments', {templateUrl: 'partial/profile/comments.html', controller: 'commentsController'});
});
Now the problem, the links to Posts, Likes, Dislikes etc do not have the profileID in them as they are set when you go to the main route, /profile#IDGoesHere.
This works when I am on the page and keep navigating by using the 'globalParams' service however, if I were to refresh the page when I was on one of the sub-pages, the data is lost.
Note: I can't make the whole page to reload which is why I used the ng-view. I could fix this by doing that but it will defeat the purpose of a single page application.
Does anyone have a good idea on this? Been pulling my hair but feel I am missing something very obvious.
Thanks in advance
Edit: as it was causing some confusion, I have added a screenshot to demonstrate how it looks like:
Got it fixed by attaching the whole < body > to a parent controller and under that controller, I used the $window.location.href and split the ID from URL and then added it to the service, which I could then add to the outer hrefs for my sub-pages, essentially making the sub-pages to have a routeParam as well

$routeProvider , Clicking same link more than once

Below is my partial angularJS code which implements routeprovider
TicketApp.config(function ($routeProvider) {
$routeProvider
// route for Create Ticket Page
.when('/CreateTicket', {
templateUrl: '../Ticket/Create',
controller: 'CreateCtrl'
})
// route for Open Ticket Page
.when('/OpenTickets', {
templateUrl: '../Ticket/MyTickets',
controller: 'MyTicketsCtrl'
})
// route for All Users Search Page
.when('/SearchUsers', {
templateUrl: '../Account/AllUsers',
controller: 'AllUsersCtrl'
})
..........
When user clicks SAME link more than once, only the
first click makes an AJAX request ,the subsequent requests
do not.
What needs to be modified so that subsequent requests to SAME link also make an AJAX call.
EDIT :
I also added below code
TicketApp.run(function ($rootScope, $templateCache, $location) {
$rootScope.$on('$routeChangeStart', function (event, next, current) {
$templateCache.remove(current.templateUrl);
});
});
did not work for me.. :(
Why do want to execute Ajax requests? It is only one request required to load the template from the server. There is no need to load it multiple time, because it shouldn't change or your architecture is not really compliant to Angular.
You could probably invalidate the templateCache and force Angular to reload the templates.
Might be this will work for your case .When the user will click the Button(the ajax call start's) you just hide it(button) once the AJAX call return a response back then show it(button).

angularjs routing based on conditions case statements

I have a different requirement for my angularJS views.
I have a cart running where an individual can checkout with 0$ as well ( some free gifts )
So, for the payment page view we came up with a different idea.
if($cart_total>0){
show payment page view;
} else {
show confirmation page view;
}
so how do I do the same in angularJS routing. My angular routing looks like this
as.config(function($routeProvider, $httpProvider) {
$routeProvider
.when('/index', {templateUrl: 'partials/index.html', controller: 'IndexListCtrl'})
.when('/shop/:id', {templateUrl: 'partials/shop.html', controller: 'ShopCtrl'})
.when('/payment/:id', {templateUrl: 'partials/payment.html', controller: 'PaymentCtrl'})
.when('/confirm', {templateUrl: 'partials/confirm.html', controller: 'ConfirmCtrl'})
.otherwise({redirectTo: '/index'});
});
So I need to show payment view only when cart_total > 0 else show confirm view.
Please help !!!
I think you have to use $route service events
PS. Here is similar question
First add a definition to your routes by declaring a constant like that.
angular.module("App")
.constant('Cart', {
showCart : 'true'
});
.when('/payment/:id',{
templateUrl:'',
access:Cart.showCart
})
Then you have to options. First in the run function check '$rootScope.$on('$locationChangeStart' event and inside it you can access the route by var location = $location.path(); var route = $route.routes[location];and then access the user role by route.access; then you can remove or add Html components.Or you can make a simple directives that dose the same route checking and use the link function to remove or add Html component

$routeProvider not firing Controller

I have a situation where the Angular $routeProvider appears to not fire controller actions on route changes.
The routes are super simple urls:
window.app = angular.module('app', ['ngRoute', 'app.filters', 'app.services', 'app.directives', 'app.controllers'])
.config([
'$routeProvider', function($routeProvider) {
console.log("app.js config launched");
$routeProvider
.when('/nav', {
templateUrl: 'temp/test.html',
controller: 'navController'
// controller: function($scope) { alert('scope called.') }
})
.when('/home', {
controller: 'homeController',
template: ' '
});
$routeProvider.otherwise({ redirectTo: '/home' });
}
]);
The controller is just an log out to verify access:
app.controller('navController', [
"$scope", "cellService",
function ($scope, cellService) {
console.log("**** navController fired");
}
]);
The initialization code fires so the routing is initialized. When I hit:
http://localhost:4333/app/#/nav
and the url changes I can see that the test.html template is accessed by the browser, but the controller never fires.
This seems to indicate the route is getting activated by the URL change, but for some reason the controller is not firing. I've tried using a function instead of a controller name, but that too never gets fired. I've also verified that the controller is valid by attaching ng-controller="navController" to an element and that fires the controller just fine.
This is a page that originally didn't have routing associated as it was basically single self-contained page that didn't need navigation. I added the route code after the fact. I added an ng-view (there wasn't one before) after which at least the template started loading - without ng-view nothing happens.
Stumped and not sure what else to look at. Help.
It turns out the problem really was operator error on my part, but I think it's a scenario that can cause issues so I'll use this as the answer.
The issue that caused this problem were two-fold:
The HTML template HTML page (via templateUrl) had an invalid URL so the page never loaded
and the controller wasn't fired because of that.
When switching to a template I used an empty template (" ") but had also
removed the ng-View directive. The ng-View directive MUST BE present
even when using an empty template. Without it the controller doesn't fire.
In both cases it didn't work and I mistakenly assumed that the controller was not getting fired which was confusing because it did fire if I explicitly hooked it up with ng-controller.
Yup plain operator error, but the latter is vitally important - without ng-View the controller doesn't fire.
What happens if you define the function externally and reference that? So instead of
.when('/nav', {
templateUrl: 'temp/test.html',
controller: 'navController'
})
It would be
.when('/nav', {
templateUrl: 'temp/test.html',
controller: navController
})
and elsewhere
function navController($scope, cellService){
console.log("**** navController fired");
}
navController.$inject = ['$scope', 'cellService'];

AngularJS $location not updated properly when using $routeProvider

I have an Angular JS application with a defaultController which controls the header of the app. Then I have some other controllers one for each view. The views are loaded in the <main>. I load the views using the $routeProvider with this code:
myapp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/login', {
templateUrl: 'templates/login.html',
controller: 'loginController'
}).
when('/dashboard', {
templateUrl: 'templates/dashboard.html',
controller: 'dashboardController'
}).
...
I am trying to display a LOGOUT button inside the header when the loaded view is the dashboard and hide it if the loaded view is the login view. In order to do that I have on the defaultController the $location object and I properly add and remove classes from the LOGOUT button with ng-class.
There is only one problem: $location gives me the correct path the first time I load the page, but after I change the view (changed by the $routeProvider) that variable is not updated anymore, so when I am actually on /#/dashboard , the $location.url is still on /login. Here the controller code:
controllers.controller('defaultController', ['$scope', 'ipCookie', '$location', function($scope, ipCookie, $location) {
$scope.url = $location.url();
...
I also tried with $window.location.hash with the same result.
Any idea?
EDIT: after the accepted answer this is what I ve added on the defaultController in order to make it work
$scope.$on("$locationChangeSuccess", function() {
$scope.url = $location.url();
});
The location is probably updated in the service after your default controller is loaded.
You can either inject the $location service into the scope and make decisions in your template based on it (then it will automatically be watched and re-evaluated) or you could listen for the $locationChangeSuccess event.
When injecting, you can simply $scope.location = $location and then use something like <a ng-hide="location.path() != '/something'">.
$location broadcasts the $locationChangeSuccess on the root scope, so you should be able to listen for it on whichever scope you have available: $scope.$on( "$locationChangeSuccess", function() { /* do something */ } );

Resources