Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Directive calling $scope function causes $rootScope:infdig

I have tried looking around at other $rootScope:infdig questions here and couldn't find one that really explained it to me well, or that I understood. Same with the AngularJs docs. I hope someone can help.

I have function that I made on the $scope that takes one parameter and calls an api GET request and returns a json object with just and "id" and a "name". This function then returns the name from the object back to the directive that calls it.

The function gets called from the directive but once it does it gets stuck in an error of a hundred of these "rootScope:infdig" per second. The directive also never renders the text of the returned "name". I know the http call works because I log the "name" in the console after.

Error Screen

Here is my controller:

owlyfm.controller('landingPageController', [ "$scope", "$log", "$http", "$location", "apiUrlsService", function ($scope, $log, $http, $location, apiUrlsService) {

 $http.get("https://api.backand.com:443/1/objects/Albums?pageSize=3&pageNumber=1&deep=true&relatedObjects=true")
    .success( function(result){
        $scope.featuredAlbums = result.data;
        //$log.info($scope.featuredAlbums);
    })
    .error( function(data, status){
        $log.error(data);
    });

    $scope.getAlbumArtist = function(artistId){

      $http.get("https://api.backand.com:443/1/objects/Artists/" + artistId)
        .success(function(result){
          var artistsName = result.name;
          $log.info(artistsName);
          return artistsName;
        });
    }
}]);

Here is where I created the directive:

owlyfm.directive("featuredAlbum", function(){

return{
    restrict: 'E',
    templateUrl: 'directives/featuredAlbum.html',
    scope: {
        albumObject: "=",
        getAlbumArtistFunction: "&"
    }
  }
});

Here is where I call the directive in the view

<div class="row fluid-container" >
    <featured-album ng-repeat="featuredAlbum in featuredAlbums" album-object="featuredAlbum" get-album-artist-function="getAlbumArtist(album)" class="col-md-4" ></featured-album>
</div>

And here is the directive itself:

    <div class="featuedAlbum">

        <div>
            <img class="img-responsive" ng-src=" {{albumObject.albumArtUrl}} "/>
        </div>

        <h4>{{ albumObject.name }}</h4>
        <h5>{{ getAlbumArtistFunction( { album: albumObject.Artists } ) }}</h5>
        <h6>{{ albumObject.releaseDate }}</h6>

    </div>

What I'm Doing

To wrap up, what I am doing is calling the api to get an album object, (I am using "Backand" BTW) Once I get this album object I render the <img> and <h> tags with the data I receive. That is working fine.

The album object has and ID, name, Date, imgUrl, and "Artists" (which is just an id for the artist). I then use this "artists" id to make another call to get the actual Artist object that is associated with it. This is where the problem arises.

The Problem

It is the http call for the artist object that is causing the loop of errors. Even though I can see in the log that it is getting the json object of the artists, it will not send it to the directive.

What I've Researched

I have read that there are problems with using ng-repeat with functions from a directive. However, I don't quite fully understand why and how it applies here nor do I know how I would change it to do what I am trying to achieve. All of the other questions on here are a little above my head.

If anyone could help me out that would be very appreciated.

like image 971
Joshua Shoemaker Avatar asked Nov 08 '22 22:11

Joshua Shoemaker


1 Answers

As said in comments, it's not a good idea to call a function that will fetch data from server inside view, because it will call multiple times, when you need it to be called only once.

You can add a property of "artistName" that will be set in "featuredAlbum" constructor.

owlyfm.controller('featuredAlbumController', [ "$scope","$http",function ($scope, $http) { $http.get("https://api.backand.com:443/1/objects/Artists/" + $scope.artistId) .success(function(result){ $scope.artistName = result.name; }); }]);

So, $http will be called only once, on controller first time run.

like image 94
Ygalbel Avatar answered Nov 15 '22 07:11

Ygalbel