Is there an issue with the React Native key not updating correctly within a for-loop?

In my React-native app, I have a function that iterates through keys in an array and retrieves the corresponding reference from Firebase.

However, I am encountering an issue within the for loop where the key value is always 3. As a result, the variable totalItemsCompleted (which represents the length of the key's value in userItemsArray) is consistently set to 3.

 listenForItems(itemsRef) {
    var userItemsArray = {
        0: [1],
        1: [5, 6],
        2: [8, 9, 10],
        3: [11, 12, 13]
    };

    var pastItems = [];
    var currentItems = [];

    for (var key in userItemsArray) {
        console.log("KEY1 " + key); //key value correct at this point
        var itemRef = itemsRef.child(key);
        itemRef.on('value', (snap) => {
            var totalItemsOnList = snap.val().items.length;
            var totalItemsCompleted = userItemsArray[key].length;
            console.log("KEY2 " + key); //key value always 3 here
            if (totalItemsOnList === totalItemsCompleted) {
                pastItems.push({
                    title: snap.val().title,
            });
            }
            else {
                currentItems.push({
                    title: snap.val().title,
                });
            }

            this.setState({
                currentItems: this.state.currentItems.cloneWithRows(currentItems),
                pastItems: this.state.pastItems.cloneWithRows(pastItems)
            });
        });
    }
}

Answer №1

The issue at hand stems from the asynchronous behavior of firebase. Your current for loop does not wait for the firebase call to complete, leading to continuous updates of the key value.

Instead of relying on the key variable, it is advisable to utilize the key from your firebase snapshot as demonstrated below:

var itemRef = itemsRef.child(key);
    itemRef.on('value', (snap) => {
        var totalItemsOnList = snap.val().items.length;
        var totalItemsCompleted = userItemsArray[snap.key()].length;
        console.log("Snapshot Key: " + snap.key()); 

Answer №2

To achieve the same result, you can easily recreate the flow using the following code:

for(let index = 0; index < 3; index++) setTimeout(() => alert(index), index * 1000)

Even though you are generating multiple instances of an anonymous function, it does not hold onto the correct 'key' value but rather refers to it by name. This means that when any of the handlers are called, the variable 'key' will have the last value it was assigned during the loop.

There are various solutions to address this issue. One simple approach is to encapsulate the creation of the handler within a self-invoked anonymous function:

temRef.on('value', ((fixedKey) => {
    return (snapshot) => { /*all other code*/ }
})(key))

Another option is to store the 'key' as an attribute value of the appropriate HTML element.

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

Trouble with Javascript slideshow: Incorrect display and malfunctioning

Struggling with implementing a slideshow banner on my webpage, despite following the W3 tutorial. Here is the code I am currently using: HTML: <div class="slide-content" style="max-width:1000px"> <img class="slidepic" src="testheadphoto.jpg" st ...

Regular expression looking for a single letter followed by a space, and then one or more digits

I attempted the following patterns: /[A-Za-z]++[ ]*+[1-9]/ and: /^[\D*]+[\s]+[\d]/ However, they are not producing the desired results. Any suggestions? ...

Timeout error occurred in Async.js because the callback was already triggered

Whenever I execute index.js, I encounter an ETIMEDOUT or ECONNRESET error followed by a Callback was already called error. Initially, my assumption was that the issue stemmed from not including a return before calling the onEachLimitItem callback. Consequ ...

Is Angular JS binding case-sensitive?

Currently, I have a dropdown menu displaying a list of countries from a JSON file. Beside it, there is a text field that correlates to the dropdown, showing the ISO 3166 alpha-2 data (e.g. CH for Switzerland). Users have the option to input the 2-characte ...

Regex inquiry: prevent a standalone dot (must be preceded by a digit or followed by a digit)

I am seeking to enable users to input decimal or integer values as shown below (A) .5 0.500 3 0 0.0 30 500000 4000.22 0. Currently, I am using the following regex pattern: factor: /^-?\d*[.]??\d*$/, The issue with this regex is that it also acc ...

Is it possible to assign a deconstructed array to a variable and then further deconstruct it?

Is there a way to deconstruct an array, assign it to a variable, and then pass the value to another deconstructed variable all in one line of code? Take a look at what I want to achieve below: const { prop } = [a] = chips.filter(x => x.id == 1); Typic ...

Switching between numerical and alphabetical input using JQuery

How can I switch between allowing character and numeric input in a textbox? I currently have a JQuery function that restricts input to numbers only $('.numeric').on('input', function (event) { this.value = this.value.replace(/[^0 ...

JavaScript URL Redirect

How to redirect a URL using JavaScript? Here's the code I've been working on: function enter() { var continuePrompt = true; var url; while (continuePrompt) { continuePrompt = false; url = prompt("Please Ent ...

Struggling to halt the continuous rendering of a component in ReactJS

In my ReactJS application, I am utilizing Redux and Redux-Thunk. Within a component using google-maps, I aim to implement the 'center_changed' feature using Markers. This means that whenever I move the marker, both the latitude/longitude and addr ...

Creating a TextArea with Javascript Validation leveraging CSS Pseudo Classes and Regex

I currently have a PHP/HTML form with input validation using HTML input patterns. To indicate that the entered input is correct, I utilize the CSS pseudo properties user-invalid/user-valid through a 'check_valid' class as shown below: input.check ...

Adjust the appearance of an element in a different parent when hovering over a specific element with a matching index

I have implemented a menu on my site in two different ways - one using text and the other using pictures. Users can click on both types of menus. Now, I am looking to create an interactive feature where hovering over a specific item in the text menu (such ...

A Step-By-Step Guide on Displaying Two Forms with Two Buttons in HTML

My goal is to develop a functionality on a webpage where users can create keys in a database. The user will need to select between two buttons, each button representing a different form to be displayed. The challenge I am facing is being able to utilize o ...

Tips for declaring a data variable in Vue with the help of APIs

I'm currently working on a project where I am integrating movie data from an API (TMDb) using Vue Routers. I have a component named 'MovieList' where I am fetching data from the API. Below is the data structure: data() { return { mov ...

What is the best way to check for incorrect or missing values when comparing two Arrays?

Can you help me with comparing two arrays, $original and $duplicate? Here is the content of my original array: print_r($original); Array ( [0] => cat423 [1] => dog456 [2] => horse872 [3] => duck082 ) And this is my duplicate array: pr ...

ES6/When.js - Dealing with promise fulfillment within a recursive chain of promises

I am currently implementing a promise chain that is recursive, meaning it calls itself until a value reaches zero. The functionality works as expected, however, I noticed that when the promise finally resolves, the output contains extra "undefined" values. ...

modifying input field with radio button selection in Jquery

Is there a way to set the input field to have a default value and then change it, or disable it with a different value? $("#tax").value(19).prop("disabled",false); $("#tax").value(0).prop("disabled",true); <script src="https://ajax.googleapis.com/aj ...

Guide on looping through a collection of objects that have child objects and generating a new custom object

I am currently working with an object list retrieved from an API. The response looks something like this: { "1/22/20": { "new_daily_deaths": 0, "total_cases": 1, }, "1/23/20": { "new_deaths": 0 ...

What is the best way to store a dynamic char array within a struct?

I am struggling to comprehend how reallocating memory for a struct enables me to insert a larger char array into the struct. Below is the definition of the struct: typedef struct props { char northTexture[1]; char southTexture[1]; char eastTe ...

Issue: Angular JS radio input not functioning as expected

Below is the code snippet in question: <div ng-controller="TestController"> <input ng-repeat="item in array" ng-model="selected.name" value="{{item.name}}" type="radio"></input> </div> <script type="text/javascript"> ...

What is causing the malfunction in communication between my React app and Express server via fetch requests?

I am currently facing an issue while trying to connect my react js frontend (hosted on localhost for testing purposes, and also on my S3 bucket) to my node.js/express server deployed on an AWS Elastic Beanstalk environment. To resolve a CORS error, I recen ...