AngularJS <a> tag links not working

JavascriptAngularjs

Javascript Problem Overview


I have an index of objects returned from search. The template has an ng-repeat where the item's URL is constructed from data in the model but in the final markup the "a" tag does not work. The ng-href and href are correct, the URL bar changes when the link is clicked but the page does not load. Doing a browser refresh after the click does get the page. So something in Angular is changing the URL bar but not triggering a load???

Can't make this reproduce in a jsfiddle because the problem seems to be in loading the json into the template after a $resource.query() function, which I can't do from a jsfiddle. With a simulated query loading static data the jsfiddle works even though the final markup looks identical.

The AngularJS template looks like this:

<div ng-controller="VideoSearchResultsCtrl" class="row-fluid">
  <div class="span12" >
    <div class="video_thumb" ng-repeat="video in videos">
      <p>
        <a ng-href="/guides/{{video._id}}" data-method="get">
          <img ng-src="{{video.poster.large_thumb.url}}">
        </a>
      </p>
    </div>
  </div>
</div>

The results look fine and produce the following final markup:

<div ng-controller="VideoSearchResultsCtrl" class="row-fluid ng-scope">
  <div class="span12">
    <!-- ngRepeat: video in videos --><div class="video_thumb ng-scope" ng-repeat="video in videos">
      <p>
        <a ng-href="/guides/5226408ea0eef2d029673a80" data-method="get" href="/guides/5226408ea0eef2d029673a80">
          <img ng-src="/uploads/video/poster/5226408ea0eef2d029673a80/large_thumb_2101146_det.jpg" src="/uploads/video/poster/5226408ea0eef2d029673a80/large_thumb_2101146_det.jpg">
        </a>
      </p>
    </div><!-- end ngRepeat: video in videos -->
  </div>
</div>

The controller code is:

GuideControllers.controller('VideoSearchResultsCtrl', ['$scope', '$location', 'VideoSearch',
    function($scope, $location, VideoSearch) {
        $scope.videos = VideoSearch.query({ namespace: "api", resource: "videos", action: 'search', q: $location.search().q });
    }
]);

Using AngularJS 1.2-rc.3. I've also tried using an ng-click and regular old onclick to get a page loaded even with static URL but the clicks never trigger the code. BTW static non-angular links on this page do work, so the Menu Bar and Sign Out work.

What have I done wrong here or is this a bug in AngularJS?

Javascript Solutions


Solution 1 - Javascript

From the mailing list I got an answer:

> Have you by any chance configured your $locationProvider to > html5Mode? If yes this would cause your problems. You could force it > to always go to the url by adding target="_self" to your tag. Give > it a shot.

I had configured to use HTML5 so adding the target="_self" to the tag fixed the problem. Still researching why this works.

Solution 2 - Javascript

Not sure if this has been updated since this post was answered, but you can configure this in application startup. Setting the rewriteLinks to false re-enables your a tags, but still leaves html5mode on, which comes with all its own benefits. I have added a bit of logic around these settings to revert html5mode in browsers where window.history is not supported (IE8)

app.config(['$locationProvider', function ($locationProvider) {

    if (window.history && window.history.pushState) {
        $locationProvider.html5Mode({
            enabled: true,
            requireBase: true,
            rewriteLinks: false
        });
    }
    else {
        $locationProvider.html5Mode(false);
    }
}]);

Angular Docs on $locationProvider

The benefits of html5mode vs hashbang mode

Solution 3 - Javascript

I know this post is old, but I recently ran into this problem as well. My .html page had the base

//WRONG!
<base href="/page" />

and the fix:

//WORKS!
<base href="/page/" />

notice the forward-slash ('/') after 'page'.

Not sure if this applies to other cases, but give it a try!

Solution 4 - Javascript

AngularJS suffers from a sparse documentation, I hope their gaining momentum will improve it. I think AngularJS is primarily intended as a SPA, and maybe the idea behind deactivating by default all a tags allows one to easily incorporate angular into some already existing html.

This allows for quick refactoring of the default "routing" behaviour of a "traditional" website (well, script pages linked between each other) into the angular routing system, which is more of an MVC approach, better suited for Web Apps.

Solution 5 - Javascript

Find this line:

$locationProvider.html5Mode(true)

change it for:

$locationProvider.html5Mode(true).hashPrefix('!')

and include this line in the head of index.html if you don't have it.

<base href="/">

Solution 6 - Javascript

I see this is old, but this is one of the top results on Google. So if you are using Angular 7, and only want to link a couple of files, then just put the into the "assets" directory:

Angular project structure for files

Now when you want to link the file you can just use the href tag as below:

  <img src="assets/ang_1.png" alt="Angular">

Note: you can only link to the assets folder by default, so you strictly have to place your files there.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpferrelView Question on Stackoverflow
Solution 1 - JavascriptpferrelView Answer on Stackoverflow
Solution 2 - JavascriptDoubleAView Answer on Stackoverflow
Solution 3 - JavascriptKevin LeView Answer on Stackoverflow
Solution 4 - JavascriptChristian BonatoView Answer on Stackoverflow
Solution 5 - JavascriptDaniel BCView Answer on Stackoverflow
Solution 6 - JavascriptBalazs F.View Answer on Stackoverflow