user2181948
user2181948

Reputation: 1938

$http call inside an ng-repeat

My web application uses AngularJS to display a list of data from an external API via an $http call. The data is fetched inside an ng-repeat by a function call.

HTML:

// 'events' does not hold all data; call getData() to get the full data
<div ng-repeat="event in events">
    {{getFullEventData(event.key)}}
    {{full_event_data.name}}
    {{full_event_data.information}}
</div>

AngularJS controller:

// Fetch and store data in 'events' scope variable
$scope.events = ...


// Fetch and store data in 'full_event_data' scope variable,
// because 'events' does not have all the data for each event
var allEventData = [];
$http({
    url: url,
    method: "GET"
}).success(function(data, status, headers, config) {
    allEventData = data;

}).error(function(data, status, headers, config) {
    // ...
});

$scope.getFullEventData = function(key) {
    for (var i = 0; i < allEventData.length; i++) {
        var fetchedEvent = allEventData[i];

        if (fetchedEvent.key === key) {
            $scope.full_event_data = fetchedEvent;
        }
    }
}

However this does not print the event name and information in the HTML (these fields are just blank). I suspect that getFullEventData() is being called before the HTTP request has finished fetching the additional data. Can anyone advise?

Upvotes: 0

Views: 345

Answers (3)

Icycool
Icycool

Reputation: 7179

Actually @charlietfl is correct, but the answer can be completed with more code. The idea is fetching additional data and then merge them with existing data.

// Fetch and store data in 'events' scope variable
$scope.events = ...

var additionalData;

// Fetch full event data
$http({
    url: url,
    method: "GET"
}).success(function(data, status, headers, config) {
    // assign additional data into events
    additionalData = data; // keep a copy of data for future use
    assignData(data);
}).error(function(data, status, headers, config) {
    // ...
});

function assignData() {
    angular.forEach($scope.events, function(event) {
        // find matching fetched event for each event in $scope.events
        var fetchedEvent = additionalData.find(function(item) {
            return event.key === item.key;
        });

        if (fetchedEvent) {
            // additional info is merged into original object
            angular.extend(event, fetchedEvent);
        }
    });
}

<div ng-repeat="event in events">    
    {{event.name}}
    {{event.information}}
</div>

Upvotes: 1

e-cloud
e-cloud

Reputation: 4491

IMO, your requeseted data from $http doesn't notify the angular to trigger change detection. So when the data arrives, getFullEventData() will not be triggered at that moment.

You have to find a way to trigger detection. like $scope.$apply or $timeout.

Upvotes: 0

charlietfl
charlietfl

Reputation: 171698

Your function doesn't make much sense.

You should be able to simply do:

<div ng-repeat="event in data">    
    {{event.name}}
    {{event.information}}
</div>

Upvotes: 0

Related Questions