angular: Bug: OnInit not fired when using Safari's back button

I am using Angular 2.0.0-beta.11 on OS X El Capitan. When Safari’s browser history back function is used, OnInit does not get fired. It seems to work fine on Chrome.

Steps to reproduce:

  1. Fire up the official Tour Of Heroes Demo
  2. Click on any hero in the dashboard
  3. Use the browser back button or click the “back” button in the demo. The dashboard doesn’t populate.

Related: #4809

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 24
  • Comments: 23 (5 by maintainers)

Most upvoted comments

This issue still exists with the new router: angular/vladivostok#64

I have an Angular 2 app ready to deploy, but it’s being held back by this bug since I need to support Internet Explorer 11.

Shouldn’t this issue block the final Angular 2 release? @vsavkin @mhevery

This still happens in chrome.

+1 same problem in ie 11 and 10

@vsavkin @mhevery any updates on this issue?

@gugamm For the time being until this issue is resolved, you can also check of IE in the above workaround to get it work…

I’ve found that the following works:

constructor(_router:Router, 
            _applicationRef: ApplicationRef) {
    _router.subscribe((uri)=> {
        if (
          Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0) // Safari
          || 
          /*@cc_on!@*/false || !!document.documentMode // IE
        {
            _applicationRef.zone.run(() => _applicationRef.tick());
        }
    });
}

I didn’t have much luck with capturing any onpageshow events after the initial load @colinskow. This might be something to do with push states, not sure though…

I did eventually find a fix to this issue which will get Safari working again which is described on Stack Overflow but basically you can use the following in your main app component to get your application to render in Safari properly on a back (and forward) button event.

constructor(_router:Router, 
            _applicationRef: ApplicationRef) {
    _router.subscribe((uri)=> {
        if (Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0) {
            // We appear to be using Safari...
            _applicationRef.zone.run(() => _applicationRef.tick());
        }
    });
}

OnInit is not only fired in Angular but in JS in general 😃 see, we had something similar in 2012: http://stackoverflow.com/questions/8788802/prevent-safari-loading-from-cache-when-back-button-is-clicked (the solutions listed there no longer work for me)

It has something to do with the back-forward cache.

Safari cache the whole page in Memory and if you navigate back the page is instantly shown without re-rendering and all scripts continue running.

The only dirty hack I have found yet its to start a time before navigating to the next page. Once you come back the timer can trigger some function.