0

I'm looking for a way (a function) to take data from a clicked element from an ng-repeat list and pass it into a controller.

My dirctive gets the data like so:

var defaultFormat = scope.release.format;
    musicInfoService.getReleaseVersions(scope.release.id)
    .success(function(data) {
        if (data.error) return;

        var format = data.versions,
          formats = scope.release.format;

        if (format !== '') {
          formats = format;
        }

        scope.defaultFormat = formats;
        dataService.setItems(scope.defaultFormat);
      })
      .error(function($scope) {
        scope.basicFormat = scope.release.format;
        dataService.setItems(scope.basicFormat);
     });

And it stores it in a factory:

app.factory('dataService', [function($scope){
   var _items= "";
   return { 
          setItems:function(value){
             _items=value;
          },
          getItems:function(){
             return _items;
          }
  };
}]);

On the controller side, the function will trigger getItems, but it just doesn't work.

function VersionController($scope, dataService) {
  $scope.versions = dataService.getItems();
  console.log($scope.versions);
}

Here's a Plunker. The list that appears under every album name should be appearing into the box that opens upon click, but the box will only show the data from the last element of the lit (the last data stored into the scope.basicFormat or scope.defaultFormat variables), so the conclusion I'm getting is that so far, the function won't trigger the setItems for each element.

6
  • The plnkr doesn't work :| Commented Mar 27, 2014 at 19:35
  • @Narretz - to me it works fine! :S Commented Mar 27, 2014 at 19:36
  • ah, sorry my noscript blocked the url with your resources Commented Mar 27, 2014 at 19:47
  • Hmm, I am sorry, I don't really understand what the problem is. Neither from your description, nor from the code. I enter an Artist, A list appears, I click on an artist, and a list of releases appears. I can filter the list. I can also search for another artist, and everything displays. Commented Mar 27, 2014 at 20:06
  • 1
    You can delete your previous question, it is the same as this question and my answer answers it as well. Commented Mar 27, 2014 at 21:07

1 Answer 1

1

It's because you call musicInfoService.getReleaseVersions thousands times, but the dataService.setItems function doesn't distinguish these calls and always overwrites results. That's why only the last result is shown.

At first fix your data service factory so that it takes the key parameter:

app.factory('dataService', [function($scope){
    var _items= {};
    return { 
          setItems:function(key, value){
             _items[key] = value;
          },
          getItems:function(key){
             return _items[key] ? _items[key] : _items["basic"];
          }
    };
}]);

Then update your setItems calls:

    // ...
    scope.defaultFormat = formats;
    dataService.setItems(scope.release.id.toString(), scope.defaultFormat);
})
.error(function($scope) {
    scope.basicFormat = scope.release.format;
    dataService.setItems("basic", scope.basicFormat);
});

And update your getItems call:

$scope.versions = dataService.getItems($scope.release.id.toString());

After this your Plunker example works.

Sign up to request clarification or add additional context in comments.

4 Comments

Hi Vorrtex! It works but there's a glitch, if the $http call comes back an error, the basicFormat won't appear. I can work around it, and add a <li ng-show="">{{release.format}}</li>, but how to I make the ng-show work only when the http call failed?
Also would be nice to minimize server calls and only make the query if the item is clicked, but all my attempts failed. If u have any pointers i'd be very appreciated!
@Eric Mitjans It's because the basic format returns different and strange strings like "cDr" or "CD, Album". But dataService.setItems expects an array, not a string, that's why it doesn't work. But I don't know what you mean by basic and what value is expected. As to minimizing server calls, create a new question on this site like "How to call a function from a directive when I click an image?", it will be easier to answer there than in comments, and also the question will be visible to more people.
As I see, in case of error you set scope.basicFormat, but do not set this value in case of success (it is undefined). So you can check Boolean(basicFormat) == true which means that there was an error. Also you can introduce a more clear name for such variable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.