Is the callback still triggered even after the off function is called?

Can someone help me with a scenario where despite calling the off on a reference, the callbacks are still being triggered repeatedly?

var ref = new Firebase('https://example.firebaseio.com/123456');

for (var n = 0; n < 1024; ++n) {
  ref.push(n)
}

ref.on('child_added', function(snapshot) {
  if (snapshot.val() > 10) {
     console.log('off') // This message is displayed multiple times.
     ref.off();
  }
});

Answer №1

When the off() function is called, it will halt the Firebase client from triggering child_added events for any new incoming data. However, it does not prevent the client from firing child_added events for existing data that has already been received.

This can lead to some interesting outcomes. For instance, consider the following code snippet:

var ref = new Firebase('https://stackoverflow.firebaseio.com/31069762');
ref.remove();

for (var n = 0; n < 1024; ++n) {
  ref.push(n)
}

ref.on('child_added', function(snapshot) {
  console.log(snapshot.val());
  if (snapshot.val() > 10) {
     console.log('off') // Printed multiple times.
     ref.off();
  }
});

The output of this would be like:

1
2
.
.
.
11
"off"
12
"off"
.
.
.
1024
"off"

Initially, the data for your reference is downloaded as one complete set when you register the listener. Subsequently, all child_added events are triggered.

Now, let's alter the sequence of the code:

var ref = new Firebase('https://stackoverflow.firebaseio.com/31069762');
ref.remove();

ref.on('child_added', function(snapshot) {
  console.log(snapshot.val());
  if (snapshot.val() > 10) {
     console.log('off') // Printed multiple times.
     ref.off();
  }
});

for (var n = 0; n < 1024; ++n) {
  ref.push(n)
}

In this scenario, we first initiate the listener and then begin pushing values. The resulting output would be:

1
2
.
.
.
11
"off"

By changing the order in this way, the process halts immediately. Since we begin listening for child_added before any data is present, the initial payload remains empty and each child is subsequently received as a separate update.

Please note that these dynamics rely on the internal mechanisms of the Firebase client, and I have not delved into how it specifically operates in practice. Hence, my concept of the "one initial packet" may differ from reality.

If your goal is to cease processing data after reaching a certain point (e.g., 10), there are two possible approaches:

  1. Employing a local flag to indicate the completion of processing, as you currently do

  2. Utilizing a Query to restrict the amount of data fetched by Firebase, rather than filtering on the client side:

    ref.orderByValue().endAt(10).on('child_added'...
    

    It is worth noting that the functionality of orderByValue was introduced in version 2.2.7 of the Firebase JavaScript SDK. It took me some time to discern why it couldn't be utilized in the JSBin environment. :-/

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

Display only one dropdown menu at a time

Hey there, I'm currently working on a dropdown menu and struggling to figure out how to keep only one item open at a time. I've tried using an array with useState for all my dropdowns but haven't been able to find a solution yet: code co ...

Cool ways to showcase HTML content in AngularJS

I am completely new to AngularJS. My goal is to display HTML content on the view using AngularJS. I initially tried using ng-model, but it displayed HTML content as a string on the view. After that, I attempted to use ng-bind-html which worked for the in ...

Presenting a Random Term from an Array in Dual Locations

<input type="button" id="btnSearch" value="Search" onclick="myFunction();" /> <div id="message"> <p></p> </div> <br> <div id="message"> <p></p> </div> <script type="text/javascript"&g ...

Ensuring the correctness of phone numbers by validating them with country codes through the use of

I'm currently working on validating phone numbers using intl-tel-input, following the example provided at Below is the code snippet I've been using: var telInput = $("#phone"), errorMsg = $("#error-msg"), validMsg = $("#valid-msg"); // initial ...

How can you make a button in Vue only visible after all API calls have successfully retrieved the data?

Is there a way to make the report button visible only after all the data has been loaded from the latest click of the budget button? Currently, when the budget button is clicked, it retrieves budgets and displays them in a Vue grid using Kendo Grid. To spe ...

Adding content to a paragraph using Jquery

I have 4 sets of data associated with a click-bind event. My goal is to retrieve the value from a hidden field in each set and display it in a paragraph elsewhere on the page when the corresponding checkbox is clicked. Currently, I'm focused on gettin ...

Encountering difficulties during the migration process from a JavaScript to a TypeScript React Component

I've encountered some challenges with configuring TypeScript in my project. Initially, I developed my application using plain JavaScript. However, eager to learn TypeScript, I decided to convert my JavaScript project into a TypeScript one. To achiev ...

The encoding for double quotation marks vanishes when used in the form action

I am attempting to pass a URL in the following format: my_url = '"query"'; when a user clicks on a form. I have experimented with encodeURI and encodeURIComponent functions as well as using alerts to confirm that I receive either "query" or %2 ...

The Bootstrap navigation pills do not function properly when using a forward slash in the tab link

I am currently working with Bootstrap and using nav pills. I have noticed that if I include a / sign in the link of a tab, it causes that specific tab to malfunction and triggers a JavaScript error in jQuery's own code when clicked on. How can I go ab ...

Patience is key when waiting for the outcome of an async Javascript function in order to obtain a result (Could it be

Hey there, I've been searching for a solution to my problem even though it's been discussed before. I'm trying to achieve something simple: creating a string like distance is : " + CalculateDistance(position);. The desired result should look ...

What is the best method in Selenium IDE for tracking an element based on its value?

While testing a website with Selenium IDE, I encountered an issue with the way elements are identified. The site utilizes something called "wickets" that change the ID of elements randomly, making it difficult for Selenium to record actions on certain elem ...

The Vue v-on:click event listener seems to be unresponsive when applied to a

I've been attempting to utilize the on-click directive within a component, but for some reason, it doesn't seem to be functioning. Whenever I click on the component, nothing happens, even though I should see 'test clicked' in the consol ...

Enable the event listener for the newly created element

I am attempting to attach an event listener to this HTML element that is being created with an API call handleProducts() function handleProducts() { var display = document.getElementById("display") var url = "http://127.0.0.1:800 ...

Hiding icons in a jquery datatable's table

I am currently developing an inline editing feature, and I would like to display a green checkmark in a column cell to indicate that the record has been updated. However, I need to hide it initially. This is how it looks at the moment: As shown, the chec ...

Using async await in a React component causes a syntax error

Struggling with setting up a basic react app using hapi.js on the server-side, I am diving into the world of webpack and babel as a newcomer. Here's a glimpse at my React component App.jsx: import React from 'react'; export default class A ...

Testing Angular: Inability to achieve full code coverage for Ternary branch in unit testing

Currently, I am attempting to test a ternary branch that utilizes the window.location property. @Injectable() export class ABCService { private hostUrl = (window.location.host.indexOf('localhost') > -1) ? 'example.com' : window.lo ...

a guide on using ajax to distribute retrieved data among various td elements

After the user presses a button, the data is saved into the database. Upon success, I need to retrieve the data from the database and place it in the appropriate td (in the same row as the clicked td). I've been able to successfully retrieve the data, ...

Uploading files with node.js and express

Currently, I am following the steps outlined in this tutorial: I have successfully followed the instructions until the section where they set up the routes without actually creating any views. The tutorial states: That's it, we have completed sett ...

Hovering triggers the appearance of Particle JS

I am attempting to add particle js as the background for my website. I have tried implementing this code snippet: https://codepen.io/nikspatel/pen/aJGqpv My CSS includes: position: fixed; z-index: -10; in order to keep the particles fixed on the screen e ...

Tips for adding and deleting elements after cloning in jQuery

I'm trying to achieve a layout similar to the one shown in this picture. It should display a delete button for each item and an add button to add more items. Check out the example here. I have managed to display the buttons individually, but I'm ...