alert user when leaving route in Ember 2.0 - javascript

Ok so i have a component i made up with a form. I would like to alert the user that he has unsaved data (if he has) when the user clicks on another link.
Now if i would not be tied to ember i would put a flag on a change event and add a window unload listener to show the actual message, However,
Since im not really leaving the window this is not getting called.
Is there any Ember event i can attach a handler to? like a change route intent event of some kind
Im interesting in knowing which is the correct event for the leaving route action, not in the something change logic.
ive tried this so far on the didInsertElement( ) method
Ember.$("body").on('unload',()=> alert('it works'));
Ember.$("window").on('unload',()=> alert('it works'));
Ember.$("body").on('unload','body'()=> alert('it works'));
any ideas?

Have you had a look at the willTransition method on your route? That will be the place to do it. Have a read of this guide to preventing and retrying transitions, as well as the willTransition method's documentation. Hope that helps!

You can catch transition event on route. It's meant to be used for this use case.
There is also action when component is being destroyed but that is meant for teardown.

Related

Is there a way to run a specific function before moving or refreshing pages in angular?

When a page is routed to another page or when a user presses the Back, Forward, or Refresh buttons, the alert window is displayed and the user selects Move, and the user wants to proceed with the initialization process.
For unload events, this does not occur in page routing. Attempted to use canDeactivate, but failed to execute a specific function after closing the alert window.
I want to know the detailed method and example.
(I'm not familiar with the anglular)
Yes. I can think of two potential solutions to your problem:
-1- If you are using Angular Material Dialog combined with canDeactivate guard logic there is a built-in method just called like that. It is named beforeClosed. It returns an Observable that you can subscribe to which will notify you when the dialog started closing. Inside this method you can execute your function.
-2- Angular router has an API called events. It essentially helps you track the status of the router. It can detect when the router starts the navigation, ends the navigation, cancels the navigation, resolved the navigation, etc...
For a complete list of API advanced events. Check this documentation link
Cool, with this API you can choose the right event that suits you and put you function inside the condition such as :
checkRouterEventToFireCustomFunctionLogic(){
this.router.events.subscribe((routerEvent) => {
if(routerEvent instanceof NavigationStart) {
// execute my custom function OR
// just console.log("Hello World")
}
});
}
PS: beforeunload event is not really good especially when it comes to Web Vitals bfcache

A context dependent navbar

I'm trying to build an Android action bar-like navbar in Ember. I would like the action bar to show the route (friendly) name and have context dependant button's on the right side. I came a long way, this jsFiddle will explain things more clearly:
jsFiddle
However, the activate event isn't I am using to figure out when a route has been changed, is only firing when one first visits the route (traversing back up the route tree won't trigger it), thus my context isn't loaded consistently.
What would be the best way to solve this problem? I know the serialize, renderTemplate and setupController fire on every route change, but none of these methods are intended to be used this way. Is there perhaps a way to add a custom event to my routes, that fires on every route change?
On a side note, I am completely new to ember so I may be going about this completely the wrong way, in that case, I am eager to hear a generally better solution, than mine.
UPDATE:
Thanks to kingpin2k's tip I was able to clean up my code a bit, for future reference here's the updated fiddle:
jsFiddle
didTransition/willTransition were created for this reason. In your case didTransition will make the most sense.
actions: {
didTransition: function(){
console.log('level two transition');
},
}
http://jsfiddle.net/FZ29Q/

Handling route changes in AngularJS

I'm struggling to handle the back button and ask confirmation to the user, if app state is dirty. Closing tab and reload is already handled via the onbeforeunload hook.
I've played with $routeChangeStart, $beforeRouteChange, etc. but can't handle it correctly.
With $routeChangeStart, the route is effectively changed before my callback is called.
What is the correct way to handle this situation?
Thanks for your help.
I believe $locationChangeStart fires when you would like it to.
you could use:
$scope.$on('$routeChangeStart', function(next, current) {
//broadcasted before a route change
// do something here
});
See more of it on : $route
Keep a model of the dirty state in a parent controller, common to all views? An alert/confirm appears if a dirty state is detected by any view's controller, with a "Cancel" button that resets $location.path(...) to the dirty page.

Backbone.js Router and back button check

Basically, I am trying to check if the previous page on every route was equal to one specific page on my site. If it is, then I want to keep the person on that view, otherwise, they can proceed to the other view.
Is there a way in a Backbone.js router, to fire off a global event that will fire before the route callback is executed?
Or, is there a way to have a catch all route that does some checking then forwards to the appropriate route.
I think overridding Backbone.History.navigate and only invoking the superclass method conditionally might work. You could also add an additional event handler for window.hashChange and window.pushState events wired up before the backbone history, and prevent the default propagation of those events if your criteria match.

Protect jQuery function from outside access

I'm using jQuery in an app which registers user clicks to perform a given action through the .click() binding, and I want this functionality to be available only through a user mousedown. One of my friends pointed out today that it's possible to run $(element).click() from a javascript terminal in Firebug (or something similar), and achieve the same functionality as clicking on the element -- something I'd like to prevent. Any ideas on how to go about doing this? Thanks for your input.
Short answer: No, you can't really prevent it.
Long answer: Any event like a click event is bound to such called Event handlers. Those handlers are functions which are executed when a given event occurs. So if you click on an element, your browser checks if any event handlers are bound to it, if so it fires them. If not, the browser will try to bubble up the event to the parent elements, again checks if there are any event handlers bound for that kind of event .. and so forth.
jQuerys .trigger() method (which is what you actually call if calling .click() for instance) just does the same thing. It calls the event handlers which are bound to a specific element, for a specific event.
EDIT
There might some simple ways to somekind of soft detect a real click, for instance you might check for the toElement property within an event object. That property is not set when triggered. But then again, you can easily fake that aswell with .trigger(). Example:
$(document).ready(function() {
$('#invalid2').bind('click', function(e){
alert('click\nevent.target: ' + e.toElement.id);
console.log(e);
});
$('#invalid1').bind('click', function(){
$('#invalid2').trigger({
type: 'click',
toElement: {id: 'Fake'}
});
});
});​
Working example: http://www.jsfiddle.net/v4wkv/1/
If you would just call $('#invalid2').trigger('click') the toElement property would not be there and therefore fail. But as you can see, you can add like anything into the event object.
What are you trying to prevent? Someone messing with your client side script? You can do things like obfuscate your code but not much other than that. But even doing this is just making it more hassle than it's worth in my opinion.
If you don't want people doing certain things move the functionality to the server.
Sorry to be bearer of bad news.
You cannot really do anything against it, it would also be possible to write the complete function and then fire it.
But why is this a problem? If somebody is changing something client side it only affects him. Or are you trying to check some data? This MUST always be done in the backend, because you can never be sure what is really sent to it.
You can check event object (which is passed as first argument to handler) originalEvent.
It will be undefined if event is simulated by .click()
But it's completely useless. You cannot use javascript for security - client has full control over it (and firebug console is just most obvious tool). Client-side security checks should be only hint for user and protection against errors, malicious input can be stopped on server-side only.

Categories