2

I'm adding a component to an existing system. Most of the time, this component will deal with one item but there's a request to support multiple items. For example, visualizing certain item in a graph and if multiple items are selected, all will be included in the same graph.

They have a service to get a specific item, or all items but not selective items.

I have something like this

        for (var i = 0; i < $scope.items.length; i++) {
          var item = $scope.items[i];
          if (item.isSelected) {
            $scope.selectedItems[item.name] = { 
                /* certain initial properties are set here */ 
                nesteItems: []
            };
            thierService.getItem(item.id)
              .then(function(data) {
                // here I want to have access to item.name to reset the properties with correct values, 
                // for example:
                $scope.selectedItems[item.name].nesteItems = data.nestedItems;

              })
          }
        }

Is there a way using promise to do this? or has to work around it with closure?

Anas Mosaad
  • 131
  • 2
  • 8
  • You already are using a promise. Can you clarify what you expect to be different in your desired result? – Peter Ashwell Jan 11 '15 at 10:03
  • item.name inside the promise is getting invalid value as item was defined outside the callback scope. – Anas Mosaad Jan 11 '15 at 10:38
  • You have the typical problem when using functions in a for-loop. The `then` will see only the `item` of the last loop iteration, not that of `items[i]`. – hgoebl Jan 11 '15 at 10:40
  • Currently to workaround this, I have something like var handler = function(name) {return function(data, status) {} } and pass it like ....then(handler(item.name)) – Anas Mosaad Jan 11 '15 at 10:40
  • I am asking if there's a better way to handle this? – Anas Mosaad Jan 11 '15 at 10:40
  • @AnasMosaad: No, [using a closure](http://stackoverflow.com/q/750486/1048572) is totally the way to go. – Bergi Jan 11 '15 at 12:07

1 Answers1

1

I think it's convenient to join thierService.getItem call for all selected items to one promise and handle result.

var selectedItemsNames = [], promises = [];

for(var i = 0; i < $scope.items.length; i++) {
    var item = $scope.items[i];
    if(item.isSelected) {
        selectedItemsNames.push(item.name);
        promises.push(thierService.getItem(item.id));
    }
}

$q.all(promises).then(function(data) {
    for(i = 0; i < data.length; i++) {
        $scope.selectedItems[selectedItemsNames[i]] = { nesteItems: data[i].nestedItems };
    };
});
Ilya
  • 326
  • 2
  • 11