kybak
kybak

Reputation: 860

Synchronizing requested data from database with ng-repeat

Each document of a collection has a "room" property. I'm trying to display each room from the collection and the number of plants associated with each room. The result will be "Room 1, 6 plants; Room 2, 2 plants; etc." The first http request successfully gets a "room" value from all documents in the "plantList" collection and displays it in the index.html. Over each iteration of the ng-repeat it will disaplay "Room 1", "Room 2" and so forth. I then use that value to pass as a url parameter in the "getplantsbyroom" http request and that gives me the information I need if I log it in the console--it will tell me the number of plants in each room. The problem is when I display the response in $scope.count the count is all the same--they all reflect the last room requested--which is obviously not correct and not what the result in the console displays. So I think the issue is that ng-repeat is producing the objects in the 'plants' array faster than the http request is able to return data from the database. So all of the $scope.counts just become whatever was called on the last iteration. I could be way off. QUESTION: Is there a way to bind incoming data from the database to each iteration of the ng-repeat directive? Or else, make each iteration wait for the data to be loaded from the database/request before moving on to the next? I've been searching for a solution for days but nothing I've found seems to address this seemingly simple problem.

server.js

MongoClient.connect(process.env.MONGOLAB_URI, function(err, db) {
    var plantList = db.collection("plantList");

app.get('/getrooms', function(req, res) {
       plantList
           .distinct("room", function(err, docs) {
           res.json(docs);
       });
    });

app.get('/getplantsbyroom/:room', function(req, res) {
        var roomReq = req.params.room;
        plantList.count({"room":roomReq}, function(err, count) {
            res.json(count);
        });
    });

});

controller.js

$http.get('/getrooms').success(function (response) {
            $scope.rooms = response;
        });

$scope.plantCount = function(room) {
        var url = '/getplantsbyroom/' + room;
        $http.get(url).success(function (response) {
            $scope.count = response;
    };

index.html

<div ng-repeat="room in rooms"  ng-init="plantCount(room)">
            <p>{{room}}</p>
            <p>{{count}} Plants</p>

Upvotes: 0

Views: 54

Answers (2)

Ronan
Ronan

Reputation: 46

You only have one $scope.count variable, you're always setting it to the same value of response (the last repeated item). You should either tie it to a room object,

$http.get('/getrooms').success(function (response) {
        $scope.rooms = response.map(function(i){return i.name:i});
    });

$scope.plantCount = function(room) {
        var url = '/getplantsbyroom/' + room;
        $http.get(url).success(function (response) {
            room.count = response;
    };

<div ng-repeat="room in rooms"  ng-init="plantCount(room)">
        <p>{{room.name}}</p>
        <p>{{room.count}} Plants</p>

or you could create an isolated scope by creating a directive for the room (which would have it's own $scope.count)

Upvotes: 1

Mhand7
Mhand7

Reputation: 537

How about adding the Id with the index for each div

<div ng-repeat="room in rooms" id="{{'room'+$index}}"  ng-init="plantCount(room,$index)">

then after passing the $index to the function, you should be able to specify which div called this ajax, the count should be part of the room object in the array, and the $index should be the $index of the object in that array.....

Upvotes: 1

Related Questions