0

I'm trying to pass data from my database to a page in my react project. The database stores the user data and the data is called with validateCookie() function. I'm getting data from the validateCookie function but I can't seem to get the data out of the function to the main page so I can use it to update the user's state and calendar and return that to update their information in the database.

The setState is not sending data to the page state. I've tried so much but I'm still new to react so I'm a bit out of my league

import ScheduleSelector from 'react-schedule-selector'
import React, { Component } from 'react';
import Moment from 'moment';
import { Row, Col, Button } from 'react-bootstrap';
import API from '../../utils/API';

class Availability extends Component {
  constructor(props) {
    super(props);
    this.state = {
    user: [],
    email: "",
    calendar: [],
    schedule: [],
  }
  // this.handleInputChange = this.handleInputChange.bind(this);
  // this.handleSubmit = this.handleSubmit.bind(this);
}

  componentDidMount() {
    this.validateCookie();
    console.log(this.state.user); // coming back empty because validate cookie is not passing data upstream
  }


  handleSubmit = (event) => {
    event.preventDefault();
    // let schedule = this.state.schedule;
    // // alert("Your availability has been submitted successfully!");
    // let ISOschedule = this.state.schedule.map(date => Moment(date).toISOString());
    // let newCalendar = this.state.schedule
    console.log(this.state.user);
    API.updateAvailability( 
      this.state.user.email, 
      this.state.user.calendar, 
      this.state.user.schedule)
      .then(r => {
        console.log(r);
    }).catch(e => {
      console.log(e);
    })
  }


  handleChange = newSchedule => {
    this.setState({ schedule: newSchedule.map(date => Moment(date).toISOString()) })
  }

  validateCookie() {
    API.validateCookie()
    .then(res => res.json())
    .then(res => {this.setState({ user: res})})
    .then(res => {
      console.log(this.state) // coming back with loading data aka empty 
      console.log(this.state.user) // coming back with all appropriate data
    })
    .catch(err => console.log(err));
    console.log(this.state.user) // coming back empty
  }

  render() {
    return (
      <div>
        <form ref="form" onSubmit={this.handleSubmit}>
          <ScheduleSelector
            selection={this.state.schedule}
            numDays={7}
            minTime={0}
            maxTime={23}
            onChange={this.handleChange}
          />
          <Row>
            <Col>
              <Button type="submit" className="float-right">Submit Availability</Button>
            </Col>
          </Row>
        </form>
      </div>
    )
  }
}

export default Availability;
CasaCoding
  • 119
  • 1
  • 2
  • 15

2 Answers2

0

I think the problem is that in your validateCookie method, you are expecting the state to change as soon as you call the setState function. It is important to know that setState() does not immediately mutate this.state but creates a pending state transition.

Refer to this answer for more information.

One solution could be to check when this.state actually gets updated before you render anything in your render function.

Swanky Coder
  • 862
  • 1
  • 8
  • 23
  • How would I check when this.state is getting updated. I noticed from the console that console.log(this.state.user) in componentDidMount is getting rendered before the data is being pulled from the validateCookie() function. – CasaCoding Nov 24 '19 at 22:20
  • Yes, that is because the `validateCookie` function is asynchronous. You can just have an if condition inside your render. For example: ```if (!this.state) return null else return ... ``` – Swanky Coder Nov 24 '19 at 22:32
  • Awesome! I think I know how to get this done now. Going to read up on this some more. Thanks! – CasaCoding Nov 26 '19 at 22:20
  • Haha! that mostly worked!! I have a new issue that I've been working on all day yesterday and today. I am getting the correct data now but its been giving me a status 500 error. – CasaCoding Nov 28 '19 at 03:16
  • Cast to string failed for value "{ userEmail: 'dj2@test.com', userCalendar: null, ISOschedule: [ '2019-12-04T01:00:00.000Z', '2019-12-04T02:00:00.000Z', '2019-12-04T03:00:00.000Z', '2019-12-04T04:00:00.000Z', '2019-12-04T05:00:00.000Z', '2019-12-04T06:00:00.000Z' ] }" at path "email" for model "User" – CasaCoding Nov 28 '19 at 03:16
  • Can you share more information like the line number? Also, it might be worth asking this in a new question thread. – Swanky Coder Dec 04 '19 at 18:46
0

Just like Swanky said, the setState() doesn't update immediately and you can listen for state change and re-render the UI. I have done some cleaning up to your setState below;

validateCookie = () => {
    API.validateCookie()
    .then(res => res.json())
    .then(res => {
        this.setState({...this.state, user: res.user})
        console.log(this.state.user);
    })
    .catch(err => console.log(err));
 }
Afia
  • 683
  • 5
  • 17