Yogev Levy Yogev Levy - 2 months ago 19
AngularJS Question

Dynamically change img ng-repeat using firebase

I have a page where a teacher can select a class (of school students). Then the teacher can create groups of students from this class by dragging avatars of the students.

I have a

drop down list of classes
and a
div
filled with avatars of the students`.

The HTML:

<select name="chosenClass" onchange="chooseClass(this.value)">
<option ng-repeat="(key, value) in techerClasses">{{key}}</option>
</select>
...
<div id="div0" ondrop="drop(event)" ondragover="allowDrop(event)" class="groupDiv">
<img ng-repeat="(key, value) in classStudents" id={{key}} src="http://placehold.it/30x30/{{value}}" draggable="true" ondragstart="drag(event)">
</div>


The controller code:

chooseClass = function (classInfo) {
if (classInfo > 0){
$rootScope.classesRef.child(classInfo).on('value', function (dataSnapshot){
$rootScope.classStudents = dataSnapshot.val().members;
});
}
}



  1. If I add data manually to the
    $rootScope.classStudents
    before
    the page loads the avatars will show correctly.

  2. console.log($rootScope.classStudents)
    after
    $rootScope.classStudents = dataSnapshot.val().members;
    confirms
    that the right data is in there.

  3. But the avatars are not showing.

  4. If I click "back" in the browser and then "forward" - the avatars
    will show. This leads me to think that I need something that will
    tell the
    <img ng-repeat...
    to refresh?


Answer

You're missing a $rootScope.$apply as you've done something outside of angular:

chooseClass = function (classInfo) {
    if (classInfo > 0){
        $rootScope.classesRef.child(classInfo).on('value', function (dataSnapshot){
            $rootScope.classStudents = dataSnapshot.val().members;
            $rootScope.$apply();
        });
    }
}

Alternatively look into using $firebaseArray:

chooseClass = function (classInfo) {
    if (classInfo > 0){
        $rootScope.classStudents = $firebaseArray($rootScope.classesRef.child(classInfo).child('members'))
    }
}