Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

undefined TypeError: Cannot call method 'replace' of undefined in Android Browser #4044

Closed
playpianolikewoah opened this issue Sep 18, 2013 · 9 comments · Fixed by #4201
Closed

Comments

@playpianolikewoah
Copy link

In Android browser I use $location.path('/login'); to route. Example:

MainMenuCtrl.$inject = ['$scope', '$location'];
function MainMenuCtrl($scope, $location) {
    $scope.doFileWeeklyClaim = function() {
        $location.path('/login');
    };
};

When I navigate away to say google.com and press back when clicking on a link the routing becomes unavailable and I get this error from line 3268 from angular.js version 1.0.8:
undefined TypeError: Cannot call method 'replace' of undefined
Everything stops working at that point.

@petebacondarwin
Copy link
Member

@petebacondarwin
Copy link
Member

From this function, right near the bottom, location.href must be undefined.

self.url = function(url, replace) {
    // setter
    if (url) {
      if (lastBrowserUrl == url) return;
      lastBrowserUrl = url;
      if ($sniffer.history) {
        if (replace) history.replaceState(null, '', url);
        else {
          history.pushState(null, '', url);
          // Crazy Opera Bug: http://my.opera.com/community/forums/topic.dml?id=1185462
          baseElement.attr('href', baseElement.attr('href'));
        }
      } else {
        if (replace) {
          location.replace(url);
          replacedUrl = url;
        } else {
          location.href = url;
          replacedUrl = null;
        }
      }
      return self;
    // getter
    } else {
      // - the replacedUrl is a workaround for an IE8-9 issue with location.replace method that doesn't update
      //   location.href synchronously
      // - the replacement is a workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=407172
      return replacedUrl || location.href.replace(/%27/g,"'");
    }
  };

@petebacondarwin
Copy link
Member

Looks like android has some issues with $location. See #3814.
Can you confirm if this also happens with 1.2.0-rc.2?
Also, any chance you could provide a cut down running example of the problem to debug? Are you just accessing a web app or are you wrapping angular into a native app?

@playpianolikewoah
Copy link
Author

This is from a webapp. Just accessing the app. When I switched out my current angular version with 1.2.0-rc.2 I got a bunch of errors so I'll make a new sample app to confirm with rc2. By tomorrow morning most likely.
I was wondering if this had anything to do with something like this:
http://stackoverflow.com/questions/15193359/does-android-support-window-location-replace-or-any-equivalent

@ajcrites
Copy link

Created test project that showcases issue: ajcrites/ng-loc-demo@8ab4b2b

Identical issue persists in latest Angular dev version: ajcrites/ng-loc-demo@01ff49f

Issue is related to bfcache. It seems the ng app will not work properly if the page is loaded from bfcache -- at least in some browsers.

Thanks to @tkayali

@tkayali
Copy link

tkayali commented Sep 25, 2013

@petebacondarwin We apologize for the delay in getting back to you. It's been a hectic week.

@ghost ghost assigned jeffbcross Sep 27, 2013
@jeffbcross
Copy link
Contributor

Here's a simple plunkr reproducing the issue. http://plnkr.co/edit/OR7xH9QeCDsGpGpFOg9e

Clicking login, then visiting google.com, then going back will cause the error to be thrown in the Android browser.

@jeffbcross
Copy link
Contributor

@ajcrites looks like BFCache is causing location to lose its reference to window.location. The issue is temporarily relieved by adding if (location !== window.location) location = window.location; inside of url(). I need to write some BFCache tests and figure the best approach to the problem.

@jeffbcross
Copy link
Contributor

@ajcrites, @playpianolikewoah and @tkayali when you have a chance, could you test your app with this build? http://ci.angularjs.org/job/angular.js-jeff/66/artifact/build/angular.js

jamesdaily pushed a commit to jamesdaily/angular.js that referenced this issue Jan 27, 2014
In the Android browser, the BFCache maintains
the state of JavaScript applications even when
navigating to another app, so that going
forward and back, to and from an application
is very fast.

Unfortunately, this can have undesired side
effects. In this instance, the location
variable was holding a reference to a stale
window.location, and was throwing errors
when going back to an Angular app after
browsing to another site.

This fix makes sure that location.url()
includes a check to make sure that location
is referencing the current window.location.

Closes angular#4044
jamesdaily pushed a commit to jamesdaily/angular.js that referenced this issue Jan 27, 2014
In the Android browser, the BFCache maintains
the state of JavaScript applications even when
navigating to another app, so that going
forward and back, to and from an application
is very fast.

Unfortunately, this can have undesired side
effects. In this instance, the location
variable was holding a reference to a stale
window.location, and was throwing errors
when going back to an Angular app after
browsing to another site.

This fix makes sure that location.url()
includes a check to make sure that location
is referencing the current window.location.

Closes angular#4044
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants