flatiron/director

Uncaught TypeError: window.onpopstate is not a function

Opened this issue ยท 11 comments

Director is throwing this error at times, from this line in the code

this.history === true ? window.onpopstate() : window.onhashchange();

Not too sure about this, a bit strange that the window doesn't have this function no?

Edit

Right so I just commented out the setTimeout and replaced it with window.onpopstate = onchange; and this fixed everything. Hopefully that's all that needs to be done.

Running into the same issue. Can't reproduce on a consistent basis.

Is there an update on this?

Remove the call to setTimeout and you should be fine unless you want to support older versions of chrome.

I'm pretty sure they fixed this bug a long time back so you should be safe to remove it.

This bug is definitely fixed - the fix shipped in Chrome 34, way back in April 2014. I find it very unlikely that anyone is still running a browser with this issue.

I don't have the setup to test this easily, but @rohan-deshpande, if you're confident in your change, could you make a pull request for it?

This is an actual issue, and not just a spurious error message, because it causes route changes that occur within half a second of page load (for example, because of an in-app redirect from a root URL) to not fire the appropriate Director handlers.

Actually, PR #279 fixes this issue but it was not merged so far.

krrg commented

I'm experiencing the same issue when I try to do a programmatic redirect. What is the status on #279 ?

Have asked the guy in that thread to post his solution to the subsequent iOS issue he was experiencing as a result of this fix for the "fix".

I've worked around this issue with the following shim of setRoute. It waits for onpopstate to become available before actually calling into director.

  (function() {
    const oldSetRoute = router.setRoute;
    router.setRoute = function() {
      if (window.onpopstate) {
        oldSetRoute.apply(router, arguments);
      } else {
        setTimeout(function() {
          router.setRoute.apply(router, arguments);
        }, 10);
      }
    }
  })();

For anyone still interested in this, I've fixed this issue in my fork and published it on npm.

@bunchjesse using your solution ๐Ÿ‘
But please notice that the arguments inside the timeout function should be changed to a variable with the original setRoute arguments

Shouldn't it be possible to assign the onpopstate function earlier? Since the Chrome bug should be long fixed by now.

window.onpopstate = function onchange(onChangeEvent) {
  for (var i = 0, l = Router.listeners.length; i < l; i++) {
    Router.listeners[i](onChangeEvent);
  }
};