0

I have a Component called SeanceManager. And in that Component I have a method that requests data from backend using fetch.

class SeanceManager extends React.Component {

    constructor(...args) {
        super(...args);

        this.state = {
            addSeanceModalShow: false,
            seances: [],
        };
        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleDeleteUser = this.handleDeleteUser.bind(this);
        this.fetchSeance = this.fetchSeance.bind(this);
    }

    componentDidMount() {
        this.fetchSeance()
    }



    fetchSeance = () => {
        fetch("/seances")
            .then(res => res.json())
            .then(
                (result) => {
                    this.setState({
                        addSeanceModalShow: false,
                        seances: result
                    });
                    console.log("Fetchime: "+this.state.seances);
                },

                (error) => {
                    this.setState({
                        addSeanceModalShow: true,
                        error
                    });
                }
            )
        console.log("l6pp: "+this.state.seances);
    }

    handleSubmit = (event, devices, interval, startDate, endDate) => {
        event.preventDefault();
        if (devices && interval && startDate && endDate) {
            var data = { devices: devices, interval: interval, startDate: startDate, endDate: endDate };
            fetch('/create', {
                method: 'post',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(data)
            }).then(function (response) {
                console.log(response)
                //TODO: Should handle here somehow ?
                // return response;
            }).then(function (data) {
                // console.log(data);
                //------------------------Method crashing here-----------
                this.fetchSeance();
               //---------------------------------------------------
            });

            // this.fetchSeance();
        }
    };

    handleDeleteUser = id => {
        fetch('/delete/'+id, {
            method: 'delete',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(id)
        }).then(function (response) {
            console.log("Kustumise response");
            console.log(response);
            //TODO: Should handle here somehow ?
            // return response;
        }).then(function (data) {
            // console.log(data);
        });
        this.fetchSeance();
        this.setState({state: this.state});
    };

    render() {
        let addSeanceModalClose = () => this.setState({ addSeanceModalShow: false });

        return (

            <MDBRow>
                <MDBCol className="col d-flex justify-content-center">
                    <MDBCard className="card col-md-6">
                        <MDBCardBody>
                            <div className="add-button-parent">
                                <MDBBtn className="add-button-child" color="cyan"
                                        onClick={() => this.setState({ addSeanceModalShow: true })}>
                                    Lisa uus seanss
                                </MDBBtn>
                            </div>

                            <form>
                                <AddSeanceFormModal
                                    show={this.state.addSeanceModalShow}
                                    handleSubmit={this.handleSubmit}
                                    onHide={addSeanceModalClose}
                                />
                                {/*{this.addToSeanceList()}*/}
                                <div className="card scrollbar-ripe-malinka ">
                                    <div className="row ">
                                        <div className="container-fluid">
                                            <div className="card-body">
                                                <h4 id="section1"><strong>Aktiivsed seansid</strong></h4>
                                                <Seances
                                                    handleDeleteUser={this.handleDeleteUser}
                                                    seances={this.state.seances} />

                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </form>
                        </MDBCardBody>
                    </MDBCard>
                </MDBCol>
            </MDBRow>
        );
    }

};

export default SeanceManager;

But when calling method this.fetchSeance() inside of the fetch method I get the:

Unhandled Rejection (TypeError): Cannot read property 'fetchSeance' of undefined

How can I call the method from within the fetch?

Richard
  • 171
  • 1
  • 2
  • 13
  • I'm wondering if your error is actually something within or after the handleSubmit, method (which you don't show). The actual error if handleSubmit were null should be "Cannot read property 'handleSubmit' of undefined". Did you cut and paste the exact error or are you paraphrasing the error? It may yet be possible that handleSubmit is undefined. But the constructor looks fine as long as you defined handleSubmit somewhere correctly. – Wyck May 15 '19 at 13:36
  • Add a couple of console.log messages or use your debugger to determine what exactly is undefined then update your question.. – Wyck May 15 '19 at 13:41
  • Edited the question and added the exact error and yes, the handleSubmit is defined correctly. I have been trying to get somewhere with console.logs, but so far I've had no luck doing so. – Richard May 15 '19 at 13:43
  • That's a pretty different question--without any code I don't see how anyone could help. – Dave Newton May 15 '19 at 13:43
  • The code you have provided doesn't even include the string `fetchSeance`. I'm getting ready to downvote... Please do a little detective work first. – Wyck May 15 '19 at 13:43
  • Alright, I will post the full code – Richard May 15 '19 at 13:44
  • at least show the part where you call `fetchData` – Wyck May 15 '19 at 13:46
  • I tried to keep the amount of code in this question minimal so it would be easier to understand but seems that was not the case. – Richard May 15 '19 at 13:49

1 Answers1

2

You've used

}).then(function (data) {
                // console.log(data);
                //------------------------Method crashing here-----------
                this.fetchSeance();
               //---------------------------------------------------
            });

when you should have used an arrow function to keep this the same as the outer scope.

}).then((data) => {
                // console.log(data);
                //------------------------Method crashing here-----------
                this.fetchSeance();
               //---------------------------------------------------
            });

Again change:

}).then(function (data) {

to:

}).then((data) => {
Wyck
  • 10,311
  • 6
  • 39
  • 60
  • Thank you a lot, was stuck on this for quite some time. But could you explain the difference between those 2? – Richard May 15 '19 at 13:55
  • 1
    Just search the web for `this` and `arrow function` You'll find it. – Wyck May 15 '19 at 13:56
  • 1
    Even SO has answers to that. https://stackoverflow.com/questions/34696686/what-is-lexical-this – Wyck May 15 '19 at 13:57
  • 1
    Also: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this – Wyck May 15 '19 at 14:00