The 3-way data binding in angularFire does not update a function

My issue involves a firebaseObject (MyFirebaseService.getCurrentUser()) being bound to $scope.user. Once successfully bound, I iterate through the object to check if it contains an "associatedCourseId" equal to a specific value ($stateParams.id). If it does, the $scope.finishLessonCount increases. The problem arises when I add a new Object to the firebaseObject (bound to user) from another page or within firebase itself, as the finishLessonCount value does not update as expected with 3-way binding. I have to refresh the page in order to see the finishLessonCount reflect the correct value. I want the finishLessonCount to change automatically using the compare function whenever more finishedLessons are added to the firebaseObject. Here is my code snippet:

MyFirebaseService.getCurrentUser().$bindTo($scope, "user").then(function(){

        for (var key in $scope.user.finishedLessons) {
            if ($scope.user.finishedLessons.hasOwnProperty(key)) {

                if ($scope.user.finishedLessons[key].associatedCourseId == $stateParams.id) {
                    $scope.finishLessonCount++;
                }
            }
        };
        console.log ($scope.finishLessonCount);
    });

UPDATE 1 based on @Kato's suggestion: I attempted to resolve this issue by extending the firebaseObject method, but unfortunately that did not work either. To simplify and avoid using factory, I needed to pass in the courseId for the operation. Below is the updated code:

       function countLessons(lessons, courseId) {
       var count = 0;
       for(var key in lessons) {
          if( lessons[key].associatedCourseId ==  courseId) {
             count++;
          }
       }
       return count;
    }

    var UserWithLessonsCounter = $firebaseObject.$extend({
      $$updated: function(snap) {
         var changed = $firebaseObject.prototype.$$updated.call(this, snap);
         this.lessonCount = countLessons(this.finishedLessons, $stateParams.id);
      }
    });

    var refTemp = new Firebase($rootScope.baseUrl + "users/" + $rootScope.userId);
    var userTemp = new UserWithLessonsCounter(refTemp);

    userTemp.$bindTo($scope, "userTemp").then(function(){
        console.log($scope.userTemp);
    });
    userTemp.$watch(function() {
      console.log("Does this run at all? " + $scope.userTemp.lessonCount);
   });

Even after updating the user object, the lessonCount value remains unchanged unless I refresh the page. Additionally, the console.log statement inside the $watch function does not execute at all. What could be causing this issue?

Answer №1

The $bindTo function returns a promise that is executed only once. It should not be mistaken for an event listener, as it does not provide real-time updates.

For a better understanding of how to handle data changes in Angular, it is recommended to read the guide and familiarize yourself with Angular's $watch method before proceeding further.

If you are new to Angular, consider using the $watch function:

Example: MyFirebaseService.getCurrentUser().$bindTo($scope, "user");

$scope.$watch('user', function() {
   for (var key in $scope.user.finishedLessons) {
      if ($scope.user.finishedLessons.hasOwnProperty(key)) {
        if ($scope.user.finishedLessons[key].associatedCourseId == $stateParams.id) {
          $scope.finishLessonCount++;
        }
      }
   };
   console.log ($scope.finishLessonCount);
});

Alternatively, after studying the AngularFire API, one may opt for $scope.user.$watch() for improved efficiency.

To streamline the process, one could utilize the $extend tool within AngularFire for scenarios like this:

// code example utilizing $extend
app.factory('UserWithLessonsCounter', function($firebaseObject) {
   return $firebaseObject.$extend({
      $$updated: function(snap) {
         var changed = $firebaseObject.prototype.$$updated.call(this, snap);
         this.lessonCount = countLessons(this.finishedLessons);
         return changed;
      }
   });
});

function countLessons(lessons) {
   var count = 0;
   for(var key in lessons) {
      if( lessons.hasOwnProperty(key) ) {
         count++;
      }
   }
   return count;
}

In the controller:

app.controller('...', function($scope, UserWithLessonsCounter) {
   var ref = new Firebase(...);
   var user = new UserWithLessonCounter(ref);
   user.$bindTo($scope, 'user');

   user.$watch(function() {
      console.log($scope.user.lessonCount);
   });
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to halt a CSS animation when it reaches the screen boundary

I put together this demo: By clicking, a red box falls down. The issue arises when trying to determine the screen size using only CSS. In my demo, I set the box to fall for 1000px regardless of the actual screen height. Here is the keyframe code snippet ...

The integration of Google Translate with Javascript on HtmlEditorExtender is experiencing difficulties and is not functioning properly

I implemented the use of a text box with ajaxtoolkit HtmlEditorExtender (Rich textbox) to translate English to Gujarati using Google translation Javascript. The translation function works perfectly with the regular text box, but encounters issues when used ...

After a span of two minutes, the Node.js and Express server terminates the connection

I am currently working with Express 4.X and Node.js 0.12. One of the routes in my application is responsible for uploading and processing files. However, I have encountered an issue where some file uploads are taking longer than the default 2-minute timeo ...

Tips for transmitting variable values through a series of objects in a collection: [{data: }]

How to pass variable values in series: [{data: }] In the code snippet below, I have the value 2,10,2,2 stored in the variable ftes. I need to pass this variable into series:[{data: }], but it doesn't seem to affect the chart. Can anyone guide me on ...

Step-by-step guide on writing to a JSON file using Node.js

I am currently developing a Facial Recognition web application using React for the frontend and Node.js for the backend. You can find more information about my project here. So far, I have completed the frontend part where users manually add 128-d descript ...

How can one obtain a distinct identifier retroactively?

One thing that I am working on is changing button images upon clicking, but this isn't the main issue at hand. Each button corresponds to unique information retrieved from the database, and when clicked, the button should change and send the appropria ...

Converting PHP variables to JavaScript using AJAX and XML communication

In order to gain a deeper understanding, I am determined to tackle this task without relying on jQuery. This means I am willing to reinvent the wheel in order to fully comprehend how it functions. My research has led me to believe that AJAX is the key to a ...

The WHATWG URL API allows creation of a new URL using the new URL

I've been experimenting with node and attempting to create an instance of the URL class to utilize its useful properties. Here's what I tried: const { URL } = require('url'); (...) http.createServer((request,response) => { let u ...

What is the best way to cancel a Promise if it hasn't been resolved yet

Let's consider a situation where I have implemented a search function to make an HTTP call. Each call made can have varying durations, and it is crucial for the system to cancel any previous HTTP requests and only await results from the latest call. ...

Dynamic Selection List Population in jqGrid

Using jqGrid 4.13.3 - free jqGrid In the Add form, there is a static input element and a select list element. The keyup ajax function is bound to the input element using dataEvents in the beforeInitData event. Once the Add form is displayed, entering a va ...

The <mat-radio-button> component does not have a value accessor specified

When working with HTML and Angular, I encountered the following issue: <mat-radio-group> <mat-radio-button [(ngModel)]="searchType"> And (Narrower search) </mat-radio-button> <mat-radio-button [(ngModel)]="searchType"&g ...

What's the most effective method for identifying a pattern within a string of text?

For the sake of honing my skills, I undertook a practice task to identify patterns of varying lengths within a specified string. How can this function be enhanced? What potential issues should I address in terms of optimization? function searchPattern(p ...

Ensure that every HTML link consistently triggers the Complete Action With prompt on Android devices

After extensive searching, I have yet to find a solution to my issue. I have been developing a web application that allows users to play video files, primarily in the mp4 format. Depending on the mobile browser being used, when clicking the link, the vide ...

Validating email addresses in AngularJS with domain verification

Hey there, I'm looking for a way to validate email input on AngularJS. I also want to include a domain check feature. For example, when the input is [email protected], I'd like to show a suggestion to the user indicating that they meant to t ...

What is causing the question mark symbol to appear at the beginning of my ajax response?

Below is my JavaScript code: $('#tags').select2({ tags: true, tokenSeparators: [','], createSearchChoice: function (term) { return { id: $.trim(term), text: $.trim(term) + ' (new tag)&ap ...

The Access-Control-Allow-Origin policy does not permit requests from applications running with an origin of null, specifically for those using a file:// URL

I am in the process of creating a webpage that utilizes jQuery's AJAX feature to fetch images from both Flickr and Panoramio. While the image retrieval from Flickr is functioning properly, I encounter an issue when attempting to use $.get(url, callba ...

How can I utilize the mapv tool created by Baidu in a Node project?

I need assistance converting the following code to a node environment. The code can be found at Here is the code snippet: var map = new BMap.Map(slice.selector, { enableMapClick: false }); // Create Map instance map.centerAndZoom( ...

Redirecting CORS in Cordova: A Comprehensive Guide

My Cordova/Phonegap app is encountering an issue while trying to retrieve certain files using AJAX. The specific error message that I receive states: XMLHttpRequest cannot load https://docs.google.com/uc?export=open&id=.... Redirect from 'https ...

It appears that the SignalR proxy is not defined

Why is $.connection.connectionhub showing as undefined? I am using webform. <script src="/scripts/jquery-1.6.4.min.js"></script> <!--Reference the SignalR library. --> <script src="/scripts/jquery.signalR-2.2.1.min.js">< ...

"Excessive use of Javascript setInterval combined with frequent ajax calls is causing significant

I have integrated the setInterval() function into my JavaScript code to make an AJAX call every 2 minutes. However, I noticed that this is causing the website to slow down over time. The website is built using Node.js. After doing some research, I came acr ...