angular.js
angular.js copied to clipboard
Bug found using $location and html5mode
In the console I get the error "Cannot read property 'indexOf' of undefined" when I try to use $location in html5mode. See this page http://www.outnorth.se/scandinavian-outdoor/produktinfo-test.php
From what I can see the problem is that AngularJS thinks the base Href must be a part of the URL, but that is not the case in our CMS we are using. This must be a bug in Angular. You must support this.
The base href on the page above is:
<base href="http://www.outnorth.se/1.0.1.0/1546/1/">
That is the real URL to a page displaying a product, but the same page is used for many different products and we are using URL rewriting to give each product a nice URL. Note that this is not the real page used to display all products, it's just a page I did setup to display the problem.
This seems related to #2805 --- however we still don't have a good way to do this yet. It's been discussed and proposed, but yeah...
Hey! What is happening with this? Are you going to implement a tag for this or what is the best solution? I am using a CMS, where it's out of my hands to alter the base-href-tag, so that is not an option and even if I could change it, it would bring me other problems. So it's not the solution. I need to be able to set a base URL for the $location service. Since I have a webshop and I have one page that is used to show every product I sell. The URL is different for every product, but it's still the same page being used.
Some examples of URL's to some products: http://www.outnorth.se/haglofs/astro-q-jacket.php http://www.outnorth.se/keen/venice-h2-w.php?group=prod_prod_grp-s1/2435#color=Black
I have turned $location off on the page above, just because it doesn't work. But I want the URL to change when I select another variant of the product. (another color or size). In browsers not supporting this I want it to fallback to changing the hash instead.
As I said in my first post above, I have put up a page just for you to see the error I get. http://www.outnorth.se/scandinavian-outdoor/produktinfo-test.php
Should I give up and not use Angulars $location to change the URL and make my own solution or are you going to solve this problem anytime soon?
Thank you for listening. Andreas
solutions have been proposed, Igor didn't like the imperative fix, so I guess we do need a directive --- but if I recall he had other issues with it, like he wanted us to resolve urls relative to our custom base url for $http, and it wasn't really clear how that would work.
This has been discussed at length but I guess we've never really decided on how this should properly "work"
If I change the method baseHref to the code below, it all works for me. Both in html5mode in a modern browser and in IE8. What is your say about this?
self.baseHref = function() {
if ($sniffer.history) {
return "/";
} else {
var url = this.url();
var initialUrl = serverBase(url);
return url.replace(initialUrl, '');
//var href = baseElement.attr('href');
//return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, '') : '';
}
};
I did also make this change some rows below the code above:
var cookiePath = '/'; //self.baseHref();
Not sure if it matters though...
After making the above changes I discovered another bug in IE8. Since I had links on my page without the attribute href, only ng-click, I got the error-msg that the variable href was undefined, so I fixed the bug with the code below:
//if (href.indexOf('://') < 0) { // Ignore absolute URLs
if (typeof href !== 'undefined' && href.indexOf('://') < 0) { // Modified by Andreas Heintze
The code is found in the function below:
/**
* @ngdoc event
* @name $location#$locationChangeSuccess
* @eventType broadcast on root scope
* @description
* Broadcasted after a URL was changed.
*
* @param {Object} angularEvent Synthetic event object.
* @param {string} newUrl New URL
* @param {string=} oldUrl URL that was before it was changed.
*/
this.$get = ['$rootScope', '$browser', '$sniffer', '$rootElement',
function( $rootScope, $browser, $sniffer, $rootElement) {
@AndreasHeintze the offending change in your most recent comment only exists in the master (1.3) branch, which doesn't support IE8: https://github.com/angular/angular.js/commit/49e7c32bb45ce3984df6768ba7b2f6a723a4ebe7
No, that code is from v1.2.20, row 9753.
We are getting this same issue. Has any progress been made on fixing this upstream?