0

I have a problem and my code works fine when I fill the variable locally. However, as soon as I start a database call, the function inside the loop no longer works. The function ensures that cards can be opened or closed. (see the example)

How can I use the functions inside the loop with a database call?

Example: https://codepen.io/CreativeBulma/pen/YbQqoQ

This function also works in a loop if I store the data in a variable as follows const

[trainingData, setTrainingData] = useState([
    {
        ...
    },
    {
       ...
    }
]);

However, as soon as I make a database call and write the data in this way, nothing works anymore setTrainingData(res.data); That is, when I call the data with the function getTrainingData().

So as soon as I fill up const trainingData with a database, nothing works anymore.

Does not work

//database call
const [trainingData, setTrainingData] = useState([]);

    const getTrainingData = () => {
        axios
            .get(`${process.env.REACT_APP_API_URL}/team/team_training-${teamid}`,
        )
            .then((res) => {
                if (res.status === 200) {
                    if (typeof res.data !== 'undefined' && res.data.length > 0) {
                        // the array is defined and has at least one element
                        setIsTrainingExisting(true)
                        setTrainingData(res.data); // The data is the same as the working code
                        console.log(res.data)

                    }
                    else {
                        setIsTrainingExisting(false)
                    }


                }
            })
            .catch((error) => {
                //console.log(error);

            });

    }

// Console.log(res.data) give me the following output
/*
[
    {
        "von": "17:00",
        "bis": "18:00",
        "tag": "Mittwoch",
        "trainingsid": 46
    },
    {
        "von": "15:00",
        "bis": "19:00",
        "tag": "Donnerstag",
        "trainingsid": 47
    }
]
*/

Works

// without database call
const [trainingData, setTrainingData] = useState([
    {
        "von": "17:00",
        "bis": "18:00",
        "tag": "Mittwoch",
        "trainingsid": 46
    },
    {
        "von": "15:00",
        "bis": "19:00",
        "tag": "Donnerstag",
        "trainingsid": 47
    }
]);

Code

 import React, { useEffect, useRef, useState } from 'react'
import bulmaCollapsible from '@creativebulma/bulma-collapsible';
import axios from 'axios'

const teamid = (window.location.pathname).split("-")[1];

function Training() {

    let collapsiblesRef = useRef(null);


    useEffect(() => {
        bulmaCollapsible.attach(".is-collapsible", {
            container: collapsiblesRef.current
        });
    }, [])

    useEffect(() => {
        getTrainingData();
    }, []);

    const [isTrainingExisting, setIsTrainingExisting] = useState(false);
    const [trainingData, setTrainingData] = useState([]);
    

/*const [trainingData, setTrainingData] = useState([
    {
        "von": "17:00",
        "bis": "18:00",
        "tag": "Mittwoch",
        "trainingsid": 46
    },
    {
        "von": "15:00",
        "bis": "19:00",
        "tag": "Donnerstag",
        "trainingsid": 47
    }
]);*/

    const getTrainingData = () => {
        axios
            .get(`${process.env.REACT_APP_API_URL}/team/team_training-${teamid}`,
        )
            .then((res) => {
                if (res.status === 200) {
                    if (typeof res.data !== 'undefined' && res.data.length > 0) {
                        // the array is defined and has at least one element
                        setIsTrainingExisting(true)
                        setTrainingData(res.data);
                        console.log(res.data)

                    }
                    else {
                        setIsTrainingExisting(false)
                    }


                }
            })
            .catch((error) => {
                //console.log(error);

            });

    }





    return (
        <div>
            <div className="card">
                <div className="card-content">
                    <div ref={collapsiblesRef} id="accordion_first">

                        {trainingData.map((d, i) =>

                        (
                            <div className="card" key={i}>
                                <header className="card-header">
                                    <p className="card-header-title">
                                        {d.tag}
                                    </p>
                                    <a href={"#collapsible-message-accordion-" + i.toString()} data-action="collapse" className="card-header-icon is-hidden-fullscreen" aria-label="more options">
                                        <span className="icon">
                                            <i className="fas fa-angle-down" aria-hidden="true"></i>
                                        </span>
                                    </a>
                                </header>
                                <div id={"collapsible-message-accordion-" + i.toString()} className="is-collapsible" data-parent="accordion_first">
                                    <div className="card-content">
                                        <p className="is-small has-text-primary has-text-weight-semibold">Tag</p>

                                        <input className="input mb-5" style={{ width: "33%" }} type="text" placeholder="Wochentag" />
                                        <p className="is-small has-text-primary has-text-weight-semibold">Uhrzeit von</p>
                                        <input className="input mb-5" style={{ width: "33%" }} type="text" placeholder="Uhrzeit von" />

                                        <p className="is-small has-text-primary has-text-weight-semibold">Uhrzeit bis</p>
                                        <input className="input mb-5" style={{ width: "33%" }} type="text" placeholder="Uhrzeit bis" />

  

                                    </div>
                                </div>
                            </div>


                        ))}
                    </div>


                </div>
            </div>

            <br />

            <div>
                <button className="button is-light"> <i class="fas fa-plus-circle"></i>&nbsp; Neu</button>
            </div>


        </div>
    )
}

export default Training
8
  • What loops are you referring to? Question/issue is unclear. Commented Oct 6, 2021 at 9:30
  • The last code section there is a loop. This loop works with both data. However, what does not work is the function. The unfolding or the closing. See the example given there to see the function. Commented Oct 6, 2021 at 9:32
  • That's just mapping your state array. The code in your codepen also doesn't match what you're asking about in your code snippets in your question. What isn't working? Can you be more specific please? Commented Oct 6, 2021 at 9:37
  • Show all your code file or we can't do anything about your bug, it's quite unclear with the given information. If I did not look at the comments I would have not know what your problem was Commented Oct 6, 2021 at 9:40
  • So the code in CodePen shows what the function should look like. A map should be able to collapse/expand which works with the extension bulmaCollapsible. This function also works in a loop if I store the data in a variable as follows const [trainingData, setTrainingData] = useState([ { ... }, { ... } ]); However, as soon as I make a database call and write the data in like this, nothing works anymore setTrainingData(res.data); Commented Oct 6, 2021 at 9:42

1 Answer 1

2

Why it's not working :

You're attaching the ref while the children are not rendered, so bulma does not know what to do to collapse your item when your components get the data from the api (since the call is async the component first render the data without the collapsible element).

What you can do to make it working :

  useEffect(() => {
        bulmaCollapsible.attach(".is-collapsible", {
            container: collapsiblesRef.current
        });
    }, [trainingData]) // <== will update bulma ref at every training data change
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.