Ryan Fonseka
Ryan Fonseka

Reputation: 255

API data rendering Issue in Child component in React

I have 2 components.

URL : http://localhost:3000/#/seat-booking?movieid=3232&name=Mortal%20Kombat&theater=SkyxX&theaterId=90&movieDate=showtdates.date&showtimeId=2130&showTime=04:30%20PM Console My data Array when the fetch called in the Parent component

{
  "data": {
    "reservedSeats": {
      "reservedSeat": [
        {
          "seatTypeId": 536,
          "seatType": "ODC",
          "adultPrice": 350,
          "childPrice": 280,
          "childAvailable": true,
          "seatRows": [
            [
              {
                "id": "A1",
                "number": "A1",
                "orientation": "north",
                "selected": true
              },
              {
                "id": "A2",
                "number": "A2",
                "orientation": "north",
                "selected": false
              },
              {
                "id": "A3",
                "number": "A3",
                "orientation": "north",
                "selected": false
              },
              null,
              {
                "id": "A5",
                "number": "A5",
                "orientation": "north",
                "selected": false
              }
            ]
          ]
        }
      ]
    },
    "nonReservedSeats": null
  },
  "success": true,
  "errorCode": null,
  "message": "Successful request!"
}

Parent Component

var movieData = []
var seatdata = []
const Mid = 0
var MoviedatatoPlan = []


export class seatBooking extends Component {

  constructor(props){
    super(props);
    this.state = {seatSdata: [], MoviedatatoPlan: [], MovieSeatList: [],}
    this.onSeatData = this.onSeatData.bind(this);
  }

  onSeatData(seatSdata) {
    this.setState({seatSdata});
    seatdata = seatSdata
    console.log(seatdata)
  }

  

    componentDidMount() {
      let movieInfo = queryString.parse(this.props.location.search)
      console.log(movieInfo.movieid) 
      this.setState(movieInfo)
      console.log(movieInfo.name)          
      movieData = movieInfo 
      // MoviedatatoPlan = movieData

      const requestOptions = {
        method: 'GET',
        headers: { 'Content-Type': 'application/json', 'client_token': 'ebd86470-7e90-4ece-9e89-1b6d4d2cbb61' }
      };
      fetch(
        // `http://595977570d12.ngrok.io/v1/seat?venueId=`+ movieData.venueId + `&movieId=`+ movieData.Mid + 
        //     `&showtimeId=` + movieData.showtimeId + `&movieDate=2021-08-05`
        `http://595977570d12.ngrok.io/v1/seat?venueId=90&movieId=3232&showtimeId=2130&movieDate=2021-08-05`
            , requestOptions)
          .then(response => response.json())
          .then((MovieSeatList) => {
            console.log(MovieSeatList.data.reservedSeats.reservedSeat)
            this.setState({ 
              MovieSeatList: MovieSeatList.data.reservedSeats.reservedSeat,
              dataLoaded: true,
             })
          }).catch(console.log);

    }
   

    render() {
const {MovieSeatList} = this.state;    

console.log(MovieSeatList)
MoviedatatoPlan = MovieSeatList
console.log(MoviedatatoPlan)
        return (
<div>
<PrimarySearchAppBar />
<div className="st_bt_top_header_wrapper float_left" style={{paddingTop:90}}>
  <div className="container container_seat">
    <div className="row">
      <div className="col-lg-4 col-md-4 col-sm-12 col-xs-12">
        <div className="st_bt_top_back_btn st_bt_top_back_btn_seatl float_left"> <Link to="/movieBooking" style={{ textDecoration: 'none' }}> &nbsp;Back</Link>
        </div>
        </div>
      <div className="col-lg-4 col-md-4 col-sm-12 col-xs-12">
        <div className="st_bt_top_center_heading st_bt_top_center_heading_seat_book_page float_left">
          <h3>{movieData.name} - English</h3>
          <h4>{movieData.movieDate} , {movieData.showtimes} </h4>
        </div>
      </div>
      <div className="col-lg-4 col-md-4 col-sm-12 col-xs-12">
        <div className="st_bt_top_close_btn st_bt_top_close_btn2 float_left"> <a href="#/movies" style={{color:"#fff"}}><i className="fa fa-times" /></a>
        </div>
        <div className="st_seatlay_btn float_left"> 
        <Link to={'/bookingSummary?movieid=' + movieData.movieid + '&movieName=' + movieData.name + '&theater=' + movieData.theater + '&venueId=' + 
          movieData.theaterId + '&showtimeId=' + movieData.showtimeId + "&showTime=" + movieData.showTime +
          '&movieDate=' + movieData.movieDate + '&seats=' + seatdata}
        style={{ textDecoration: 'none' }}>Proceed</Link>
        </div>
      </div>
    </div>
  </div>
</div>


<SeatPlan onData={this.onSeatData} dataParentToChild = {MovieSeatList}/>
</div>
        )
    }
}

export default seatBooking

Child Component

import React, {Component, useState} from 'react'
 
import SeatPicker from 'react-seat-picker';
import Screen from '../../images/content/screen.png';
import queryString from 'query-string';

var seats = [] 
var MovieSeatList = []
var data 
var seatPLan = []
export default class SeatPlan extends Component {

constructor(props){
  super(props);
  this.state={
    MovieSeatList: this.props.dataParentToChild
    
  }
  console.log(MovieSeatList)
}




  state = {
    loading: false
  }
 
  addSeatCallback = ({ row, number, id }, addCb) => {
    this.setState({
      loading: true
    }, async () => {
      await new Promise(resolve => setTimeout(resolve, 1500))
      console.log(`Added seat ${number}, row ${row}, id ${id}`)
      const newTooltip = `tooltip for id-${id} added by callback`
      addCb(row, number, id, newTooltip)
      this.setState({ loading: false })
    })
  }
 
  addSeatCallbackContinousCase = ({ row, number, id }, addCb, params, removeCb) => {
    this.setState({
      loading: true
    }, async () => {
      if (removeCb) {
        await new Promise(resolve => setTimeout(resolve, 750))
        console.log(`Removed seat ${params.number}, row ${params.row}, id ${params.id}`)
        removeCb(params.row, params.number)
      }
      await new Promise(resolve => setTimeout(resolve, 750))
      console.log(`Added seat ${number}, row ${row}, id ${id}`)
      const newTooltip = `tooltip for id-${id} added by callback`
      addCb(row, number, id, newTooltip)
      // seats = {number}
      seats.push(number)
      this.setState({ loading: false })
      // console.log(seats)
      this.props.onData(seats)
    })
  }


 
  removeSeatCallback = ({ row, number, id }, removeCb) => {
    this.setState({
      loading: true
    }, async () => {
      await new Promise(resolve => setTimeout(resolve, 1500))
      console.log(`Removed seat ${number}, row ${row}, id ${id}`)
      // A value of null will reset the tooltip to the original while '' will hide the tooltip
      const newTooltip = ['A', 'B', 'C'].includes(row) ? null : ''
      removeCb(row, number, newTooltip)
      this.setState({ loading: false })
      seats.splice(seats.indexOf(number), 1);
      this.props.onData(seats)
    })
  }


 



  render() {

    const {MovieSeatList} = this.state;
    console.log(MovieSeatList)


    seatPLan = MovieSeatList
    console.log(seatPLan)
    
    const {loading} = this.state
    return (
      <div>
        <div className="col-lg-4 col-md-3 col-sm-3 col-xs-3">{data}</div>
        <div className="col-lg-4 col-md-6 col-sm-3 col-xs-3" style={{ marginTop: '10px', alignItems:'center' }}>
        <img src={Screen} width="450px"/>
        {seatPLan.map((seatingPlan) => {
          return(
            <SeatPicker
            addSeatCallback={this.addSeatCallbackContinousCase}
            removeSeatCallback={this.removeSeatCallback}
            rows={seatingPlan.seatRows}
            maxReservableSeats={5}
            // alpha
            // visible
            selectedByDefault
            loading={loading}
            tooltipProps={{ multiline: true }}
            continuous
          />
          );
        })}
        </div>
        <div className="col-lg-4 col-md-3 col-sm-3 col-xs-3"></div>
      </div>
    )
  } 
}

Upvotes: 0

Views: 225

Answers (1)

user14361391
user14361391

Reputation:

The problem could be the API call on the parent is not asynchronous and thus the child could have no data from parent until the parent completes the API call

getSeats = async() =>
{
  try
  {
    await fetch("")
  }
  catch(e)
  {
    console.log(e)
  }
}

import { Component } from "react";
// class based component (Older React)

class Parent extends Component{

  componentDidMount()
  {
    this.getSeats()
  }

  getSeats = async() =>
  {
    try {
      await fetch("")
    } catch (error) {
      console.log("error", error)
    }
  }
}

Upvotes: 1

Related Questions