The array contains no elements, yet it is not empty, and when stringified with JSON.stringify, it results

I've been working on developing an event registration page for a school club I'm involved in, but I'm encountering a problem where my program is unable to correctly read the contents of an array and display each item as a ListItem within a List. When I trigger the function, the boolean expression this.state.events.length !== 0 returns False, even though console.log(this.state.events) confirms that the array is not empty.

What could be causing this issue and how do you suggest I tackle fixing it?

On a side note: I would greatly appreciate any feedback or critiques of my code. I'm relatively new to JavaScript, React, and MaterialUI and am eager to enhance my skills.

class EventSelector extends Component {

    constructor(props){
        super(props);

        this.state = {
            events: []
        }

    }

    componentDidMount = () => {

        var lst = [] // list of events with {key: "event_name"}

        const eventsRef = db
                        .collection('events'); 

        const offeredRef = eventsRef
                        .where('allowRegistration', '==', true)
                        .get() 
                        .then((querySnapshot) => {
                            querySnapshot.forEach((doc)=> { 
                                lst.push({key: doc.data().name, id: doc.id})
                            })
                        })

        this.setState({ events: lst })
        return true;

    }

    EventList = (events) => {

        const { classes } = this.props;

        return(

            <div>
                <Grid container item 
                        direction='column' 
                        alignItems='center' 
                        justify='center' 
                        style={{ maxHeight: '70vh', maxWidth: '50vw' }} 
                        spacing={5}>

                        <Grid item>
                            <h1 className={classes.h1}>Upcoming Events</h1>
                            <h2 className={classes.h2}>Please select an event to sign up</h2>
                        </Grid>

                    <Grid container item direction='row' justify='center' spacing={5}>

                        <List component='b' subheader={<ListSubheader componenet='b'>Upcomming Events</ListSubheader>}>
                            {events.map(({key, id}) => {
                                return (
                                    <div key={id}>
                                        <ListItem button>
                                            <ListItemText inset primary={key}/>
                                        </ListItem>
                                    </div>
                                );
                            }) }

                        </List>

                    </Grid>   

                </Grid>
            </div>
        );
    }


    render = () => {

        const { classes } = this.props;

        console.log(this.state.events)
        var obj = Object.assign({}, this.state.events)
        console.log(JSON.stringify(obj))

        return (this.state.events.length !== 0 ? <h1>{JSON.stringify(this.state.events)}</h1> : <h2>Loading</h2>)

    
    }
}

export default withStyles(styles)(EventSelector);

View console output with Object.assign()

View console output without Object.assign()

Answer №1

From my perspective, your code looks fine. A fascinating aspect of React is that every state change triggers a new call to the render method.

state = { events: [] };

componentDidMount() {
  // const lst = ...
  this.setState({ events: lst });
  // no need return here
};

render() {
  console.log(this.state.events);
}

The first time it runs, it will display [] since your state is initially set to an empty array. Once the component is mounted, the events variable will display as if it has been populated.

An alternative way to write this code is by using a functional component:

import { useState } from 'react';

const EventSelector = () => {
  const [events, setEvents] = useState([]);

  useEffect(() => {
    // const lst = ...
    setEvents(lst);
  }, []);

  return events.length !== 0 ? (
    <h1>{JSON.stringify(this.state.events)}</h1>
  ) : (
    <h2>Loading</h2>
  );
}

In my opinion, functional components are easier to comprehend. This code functions just like yours, with the same expected behavior.

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

Extract the content of an element and incorporate it into a script (AddThis)

HTML: <div id="file-section"> <div class="middle"> <p class="description"> Lorem ipsum... </p> </div> </div> jQuery: var share_on_addthis = { description: $('#file-section ...

Using AngularJS, you can easily merge one array of data into another array

In my coding environment, I am working with two arrays. The first array is called `$scope.workingSchedules` and it contains data related to working hours for different days of the week. $scope.workingSchedules=[ { ...

Utilize auto-suggestion feature for populating dynamically created input fields with information sourced from the

I have searched through numerous questions on stackoverflow related to my issue, but I was unable to apply any of them to solve my problem. Therefore, I am providing the files that I have been working with. I have successfully implemented autocomplete fe ...

The ng-switch function is not generating the desired code output

In my Ionic app, I have the following code snippet that I am currently viewing with ionic serve. However, when the initial ng-switch statement triggers... <span ng-switch="post.enclosure"> <span ng-switch-when="[]"> <p>def&l ...

"Troubleshooting issue: Unable to retrieve grid data from Google Sheets API v4 when integrated

I've implemented a function within a React component that retrieves JSON data from an API request and logs it: async function getAllSheets() { let response; try { response = await window.gapi.client.sheets.spreadsheets.values.batchGet( ...

Node 18 is having trouble locating NPM and is unable to locate the module './es6/validate-engines.js'

Previously, I attempted to install Node.js without any issues. However, this time around, I am encountering difficulties accessing the npm package. While I can successfully retrieve the version of Node.js after installation, attempting to check npm -v or w ...

What is the best way to align a Fab button within a circular progress indicator?

I'm attempting to center a FAB inside a circular progress bar. The suggestion was to use relative positioning for the parent and absolute positioning for the children. My goal is to maintain responsiveness, so that it looks consistent even when the sc ...

Is it possible to use mapDispatchToProps in Redux without mapStateToProps?

As I dissect Redux' todo example to gain a deeper understanding, I came across the concept of mapDispatchToProps. This feature allows you to map dispatch actions as props, which led me to consider rewriting addTodo.js by incorporating mapDispatchToPro ...

Having difficulties creating a react web application with ESLint; encountering an issue where ESLint is unable to locate the "developit" configuration to extend from

When running npm run build, my React app encounters an issue. During normal operation with npm start, everything works fine. Oops! Something went wrong! :( ESLint: 6.8.0. ESLint couldn't find the config "developit" to extend from. Please verify the ...

Ways to verify whether an array contains any of the specified objects and then store all those objects in Supabase

Perhaps the title of my question is not very clear, but I find it difficult to summarize in just one line. To provide context, it would be best to see the JavaScript query I'm making for Supabase and its response. The data: [ { title: 'Th ...

Upon clicking, Vue triggers form validation in Laravel

I have encountered an issue that I am unable to solve by myself: Within my Laravel view, I have included a form in the following manner {!! Form::open(array('route' => ['reports.store', $project->id], 'data-parsley-validate& ...

Angular, JavaScript, and PHP are three powerful programming languages that

This file contains HTML code <ul class="list"> <li id="numword" data-score="{{item.score}}" class="" ng-repeat="item in words track by $index"> {{item.word}} {{item.score}} </li> </ul> Here is the visual representa ...

Merge is showing an error message indicating that I am trying to import runtime.js from outside the src directory, even though the file structure remains unchanged

I've noticed that most questions about a similar issue involve users intentionally trying to import files from outside their project. However, I recently performed a merge between branches that did not alter my folder structure, yet I'm encounter ...

Direct all paths to the base path "/" using Express

Is there a way to redirect all URLs containing "/something" in Express to the base path "/:=", while still maintaining additional paths to their respective pages? For instance, I would like to implement the following redirects: "/something" redirects to ...

Implementing basic authentication with React and Node.js

I'm currently utilizing the fetch API to send requests from a ReactJS frontend to a Node.js backend with Basic Authorization using the following code... React fetch(baseUrl, { method: 'get', headers: { Accept: 'application/json ...

How to efficiently import Xlsx and csv files using AngularJS

I am looking for a way to extract data in json format from each line of xlsx and csv files using AngularJS. Currently, I am utilizing the angular-file-upload library to access the file as shown below: $scope.LatLongUploader = new FileUploader({ //url ...

Engaging with the crossrider sidepanel extension

When it comes to the crossrider sidepanel, I prefer using an iframe over js-injected html to avoid interference with the rest of the page. However, I am struggling to establish any interaction between my browser extension and the iframe. I believe adding ...

Is there a way to still access the data from a radio button even if it hasn't been selected?

I'm currently working on a questionnaire feature and facing an issue where I need to capture all answers, even if the radio button is not checked. Here's a snippet of the HTML code: $('input:radio').each(function () { if ($(this). ...

Issues with Docker port publishing on Windows 10

Recently, I've been diving into the world of Docker and ran into an issue with port publishing from a docker container to the host machine. To start off, I built an image for a simple React app (using Vite) by running the command docker build -t reac ...

Update class name in React component based on state change

My current setup involves the setting of active and class flags as shown below: constructor(props) { super(props); this.state = {'active': false, 'class': 'album'}; } handleClick(id) { if(this.state.active){ this.s ...