Setting:
I have an angular app.
What I have:
I have this: ui-sref="providerDetail({id:provider.id})" functioning.
It is a functioning link to a page giving details on a given provider.
What I want:
I have a button that submits a form and makes a new provider. This works. But I also want this button to forward the user to that new provider's detail page.
I have a function running that prints the id of the new provider to the console when it is made, I just can't figure out how to forward the user to the appropirate location.
Note:
I can add this to the function:
window.location = "/dashboard.html#!/providerDetail/" +id;
And it will take me to the new page, but I get this impression that this is a bad route to take.
Don't manually change the URL in AngularJS application, do it in Angular way so that you don't need to worry about manually kick of digest cycle. From function you could call $state.go method to navigate between states.
function myFunction(id) {
$state.go('providerDetail', { id: id})
}
Note: Please make sure you inject $state inside you controller.
Related
I have an AngularJS web app. When a user gets to my domain root URL root-domain/ my app checks automatically his navigator language and if different than english it should automatically include the language in the url, like root-domain/es. This makes my controller reloads and I would like to avoid this for performance and user experience purposes.
I have read the solution provided Can you change a path without reloading the controller in AngularJS? by #Vigrond but for some reason I get next error:
TypeError: $rootScope.$on is not a function
at LocationUrl.$location.path (app.js:140)
at Constructor.HomeCtrl (home.js:15)
in line: var un = $rootScope.$on('$locationChangeSuccess', function () {
According to the approach, you don´t have to do anything else, but I guess I´m missing something.
If an user is coming from an specific page i need to do get some values out of a cookie and change what the users sees.
Now, the issue is that i cannot find a way to view what page the user is coming from.
EDIT: This is intended to capture when the users clicks back in a page and save the state of the previous page.
Any ideas?
Thanks in advance
Solved. Every time i load a page i'm saving the url, so when i get to this page i just have to read it to tell. Thanks!
You can use browser history in our javascript or you can write your last page in cookies and get the last link then update it
Using cookies will indeed fix this for you. So when a user goes to a new page - set a cookie like:
app.controller('myController',['$scope', '$location', $cookies], function($scope, $location, $cookies){
if($cookies.get('page') == '/index'){
//do stuff if user came from index
}
$scope.pageChanged = function(value){
$cookies.put('page', value);
$location.path('/index');
}
}
just make sure you use the pageChanged function to set your page every time user changes pages.
Using the $routeProvider you can use the resolve function to detect when a new route has been loaded.
Another way would be to listen for the event $routeChangeSuccessor $routeChangeError and get the information needed from the service $location or $route.
If you want a sample just ask me, I'll try to post one as soon as I have free time.
I'm fairly new to angular, so bear with me. :-)
I have a list of contacts in one view. I put together a service with some setter and getter functions to hold the contact ID. When the user clicks a contact on the list view, it sets the ID in the service and moves to the edit form view. This is working well, but when I'm done editing and click to go back to the list view I want to clear the variables in the service. How would I do that?
I found one other answer on this topic, but I think it's using the built in angular router instead of ui-router.
Angular updating and clearing factory variables
Also, wouldn't the method in that answer also clear the variables when the user moved from the list to the edit form in the first place?
Thanks!
If it's a route change you can use $locationChangeStart, see $location
For example in your edit controller, register for the event on route change:
var onloc = $scope.$on('$locationChangeStart', function (event, newUrl, oldUrl) {
myService.cleanUp(whatever);
onloc();
});
My angular app is non-standard in that we don't use route provider or UI router. WE use a durandal style of navigation that swaps out views using $http.
locationChangeStart never fires I think due to the fact that we are not changing our URL once in the SPA (though we plan to do so in the future sometimes). I can't test this, but if we remain in the SPA and we change the URL to point to a new view thru code (again, not using routeProvider/UiRouter) should I expect this event to fire?
My main issue is that I cannot handle these events: manual url change, back/forward/history buttons, external link clicks
I see $browser#onUrlChange is the function that broadcasts the $locationChangeStart event but that function only gets called on page load for me, but it seems to be exactly the code that should be getting called.
Documentation:
$browser#onUrlChange
It's only called when the url is changed from outside of angular:
user types different url into address bar
user clicks on history (forward/back) button
user clicks on a link
It's not called when url is changed by $browser.url() method
It says this part also:
NOTE: this api is intended for use only by the $location service. Please use the {#link ng.$location $location service} to monitor url changes in angular apps.
I don't know how to 'use $location service to monitory url changes', so I am listening to the $locationChangeStart event:
$rootScope.$on('$locationChangeStart', function(event, next, current) {
// Breakpoint hit here on page load only
var x = 0;
}
Why doesn't the onUrlChange/$locationChangeStart functions run for me?
thanks!
I'm working on an AngularJS app that has a catch all route (eg, .when('/:slug', {...)) which is necessary to support legacy url formats from a previous (non-angular) version of the app. The controller that responds to the catch all tries pulling a related object, and, if not found, redirects to a 404 page using the $location.path method. This works at getting the user to the 404 page, but when the user hits back in their browser it takes them back to the page that forced them to the 404 page in the first place and they end up being unable to escape the cycle.
My question is if there is 1) a better pattern for handling this situation, or 2) if there is a way to reroute the user that doesn't force a history push state in the browser?
You can change the url without adding to the history state, found here under "Replace Method". This is effectively the same as calling HTML5's history.replaceState().
$location.path('/someNewPath').replace();
I haven't found that it's possible to change the view without changing the url. The only method to change the view, that I've found, is to change the location path.
The normal operation of the route system is for the $route service to watch for the $locationChangeSuccess event and then begin loading a route. When it's done loading the template, performing the resolve steps and instantiating the controller it then in turn broadcasts a $routeChangeSuccess event. That $routeChangeSuccess is monitored by the ng-view directive, and that's how it knows to swap out the templates and scopes once the new route is ready.
With all of the above said, it may work to have application code emulate the behavior of the $route service by updating the current route and emitting the route change event to get the view to update:
var errorRoute = $route.routes[null]; // assuming the "otherwise" route is the 404
// a route instance is an object that inherits from the route and adds
// new properties representing the routeParams and locals.
var errorRouteInstance = angular.inherit(
errorRoute,
{
params: {},
pathParams: {},
}
);
// The $route service depends on this being set so it can recover the route
// for a given route instance.
errorRouteInstance.$$route = errorRoute;
var last = $route.current;
$route.current = errorRouteInstance;
// the ng-view code doesn't actually care about the parameters here,
// since it goes straight to $route.current, but we should include
// them anyway since other code might be listening for this event
// and depending on these params to behave as documented.
$rootScope.broadcast('$routeChangeSuccess', errorRoute, last);
The above assumes that your "otherwise" route doesn't have any "resolve" steps. It also assumes that it doesn't expect any $routeParams, which is of course true for the "otherwise" route but might not be true if you use a different route.
It's unclear what of the above is depending on implementation details vs. interface. The $routeChangeSuccess event is certainly documented, but the $$route property of the route instance seems to be an implementation detail of the route system given its double-dollar-sign name. The detail that the "otherwise" route is kept in the route table with the key null is possibly also an implementation detail. So with all of this said, this behavior may not remain functional in future versions of AngularJS.
For more information you could refer to the ng-view code that handles this event, which is ultimately what the above code is trying to please, along with the event emitting code that I used as the basis for the above example. As you could infer from these links, the information in this post is derived from the latest master branch of AngularJS, which at the time of writing is labelled as 1.2.0-snapshot.