addlistener
addlistener

Reputation: 871

$rootScope event preventDefault doesn't stop succeeding handler

I'm using ui-router and registered two $stateChangeStart handlers for login page redirection.

function func1(e,to,toParams, from, fromParams){
    ....
    if (notAuthenticated) {
        e.preventDefault();
        $state.go('login');
    }
}

function func2(e,to,toParams, from, fromParams){
    ...
    console.log('func2', from, to, e.defaultPrevented);
}

$rootScope.on('$stateChangeStart', func1);
$rootScope.on('$stateChangeStart', func2);

As func1 preventDefault(), I can see that in func2 e.defaultPrevented is true. I just don't understand why preventing default in func1 does not stop func2 from executing. Is this behaviour by design? And if it is, what does "default" mean?

Here's the plunk: http://plnkr.co/edit/o81NVo?p=preview You can clear the console and rerun it to see the log.

Upvotes: 3

Views: 558

Answers (1)

Daniel Beck
Daniel Beck

Reputation: 21485

You're close to the answer -- since there is no built-in 'default' event to prevent, preventDefault only sets the defaultPrevented boolean; you have to check that boolean in func2 and bail out if it's true. (There could be any number of functions watching for stateChangeStart; angular doesn't have any direct way of knowing that func2 is what you intend to be the "default" one.)

(If the original event was $emited, you could use stopPropagation to prevent it bubbling further up the DOM; this is possible because $emits go in a defined order, each node has only one parent. $broadcast events can't be cancelled, only flagged, because a broadcast could reach down to sibling nodes "simultaneously" (or more likely in an undefined order.)

Upvotes: 2

Related Questions