1

Hello im new to react and Im hoping someone can help out. So I have a JSON file from an api i made and this is the request to get all theaters, I only have one theater for this api but that theater has multiple movies, showtimes

  {
    "theatreId": 1,
    "theatreName": "Scotiabank Theater Chinook",
    "movies": [
      {
        "movieId": 4,
        "movieName": "Now You See Me",
        "dateAdded": "2022-12-31",
        "showtimes": [
          {
            "showtimeId": 14,
            "showtimeDate": "2022-12-10",
            "showtimeTime": "11:00:00",
            "seats": [
              {
                "seatId": 218,
                "seatNum": 10,
                "theTicket": null
              },
              {
                "seatId": 220,
                "seatNum": 12,
                "theTicket": null
              },
              {
                "seatId": 214,
                "seatNum": 6,
                "theTicket": null
              },
              {
                "seatId": 210,
                "seatNum": 2,
                "theTicket": null
              },
              {
                "seatId": 219,
                "seatNum": 11,
                "theTicket": null
              },
          ....{more data points here}

I am trying to create a multi level select option dropdown list i.e. when I select a menu from the first dropdown, based on that option the next dropdown would be a list of options of what was in the previous option was.

multi level dropdown list

In this case, I have just one cinema, "Scotibank Chinook" when I select that cinema option, I want the next option which is movie to be a list of movies based on "movies" since its values is an array of objects and the same for showtimes and seats as seen in the JSON file.

I have a react code where I make each name that has an array of objects to make useState list of those object names, my main issue is to navigate into the array of objects and setState of the List to be the List of objects

import React, {useState,useEffect} from 'react';
import axios from 'axios';

function Form() {
    const [theaterName, setTheaterName] = useState("")
    const [movieName, setMovieName] = useState("")
    const [showTime, setShowTime] = useState("")


    const [theaterList, setTheaterList] = useState([{'theatreId':''}])
    const [movieList, setMovieList] = useState([{'movieId':''}])
    const [showTimeList, setShowTimeList] = useState([{'showtimeId':''}])


    useEffect(() =>{
        fetchTheater();
        fetchMovie();
        fetchShowTime()
    }, [])

    const fetchTheater = () => {
      axios.get('http://localhost:8080/api/v1/theatre')
      .then(response => {
        console.log(response.data)
        setTheaterList(response.data);
      })
      .catch(error => console.log(error));
    }

    const fetchMovie = () => {
      axios.get('http://localhost:8080/api/v1/movie')
      .then(response => {
        console.log(response.data)
        setMovieList(response.data);
      })
      .catch(error => console.log(error));
    }

    const fetchShowTime = () => {
      axios.get('http://localhost:8080/api/v1/showtime')
      .then(response => {
        console.log(response.data)
        setShowTimeList(response.data);
      })
      .catch(error => console.log(error));
    }

    const handleTheaterChange = (event) =>{
        setTheaterName(event.target.value);
    }


    const handleMovieChange = (event) =>{
      setMovieName(event.target.value);
    }

    const handleShowTimeChange = (event) =>{
      setShowTime(event.target.value);
    }
    

    const saveBtn = (e) => {
        e.preventDefault();
        console.log('Theater Selected',theaterName);
        console.log('Movie Selected',movieName);
        console.log('Showtime Selected',showTime);

    }

    return (
        <div>
          <div className="container-fluid">
            <div className="row">
              <div className="col-sm-4">
                <h2 className="alert alert-warning">Movies</h2>
                
                <br />
                
                <select className="form-control" value={theaterName} onChange={handleTheaterChange}>
                  <option value="">Choose theatre</option>
                  {theaterList.map(theater => (
                  <option key={theater.theatreId} >
                    {theater.theatreName}
                  </option>
                  ))}
                </select>

                  <br/>

                  <select className="form-control" value={movieName} onChange={handleMovieChange}>
                    <option value="">Choose Movie</option>
                    {movieList.map(movie => (
                      <option value={movie.movieName} key={movie.movieId} >{"Hello"}</option>
                    ))}
                  </select>

                  <br/>

                  <select className="form-control" value={showTime} onChange={handleShowTimeChange}>
                    <option value="">Choose showtime</option>
                    {showTimeList.map(showtime => (
                      <option value={showtime.showtimeDate} key={showtime.showtimeId} >{showtime.showtimeDate}</option>
                    ))}
                  </select>


                  <button className="btn btn-primary" onClick={saveBtn}>Save</button>
              </div>
            </div>
          </div>      
        </div>
      )
}

export default Form

currently I am accessing each option by fetching the individual api endpoints for the the options and setting the state to a setState List

Jay Jay
  • 33
  • 8

1 Answers1

0

You only need one api which is the theater endpoint. I don't know which backend you are using, but you need one response, it should contain all these nested lists. then simply in react, use this logic

import React, {useState,useEffect} from 'react';
import axios from 'axios';

function Form() {
    const [theater, setTheater] = useState("")
    const [movie, setMovie] = useState("")
    const [showTime, setShowTime] = useState("")   

    const [theaterList, setTheaterList] = useState([])
    const [movieList, setMovieList] = useState([])
    const [showTimeList, setShowTimeList] = useState([])


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

    const fetchTheater = () => {
      /*using fetch
      fetch(`http://localhost:8080/api/v1/theatre`,
            {   
            headers : { 
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            }
            
        }).then(res => res.json()).then(
            data => {
                console.log(data);
                setTheaterList(data);
                //setReady(true);
                console.log("theater id: "+data[0].theaterId);
                
        }).catch(error => {
            console.log(error);
        });*/

       // using axios
        axios.get('http://localhost:8080/api/v1/theatre')
      .then(response => {
        console.log(response.data)
        setTheaterList(response.data);
      })
      .catch(error => console.log(error));
    }


    const handleTheaterChange = (event) =>{
        let id = event.target.value;
        console.log("theater changed: "+id);
        //setTheater(event.target.value);
        theaterList.map(theater => {
        console.log(theater.theaterId);
        if(theater.theaterId === parseInt(id)){
            console.log("theater found "+theater.theaterId);
            setMovieList(theater.movies);
            setTheater(theater);
        }
        
    });
        
    }


    const handleMovieChange = (event) =>{
        let id = event.target.value;
        console.log("movie changed: "+id);
            
        movieList.map(movie => {
            console.log(movie.movieId);
            if(movie.movieId === parseInt(id)){
                console.log("theater found "+movie.movieId);
                setShowTimeList(movie.showtimes)
                setMovie(movie);
            }
        });

    }

    const handleShowTimeChange = (event) =>{
        let id = event.target.value;
        console.log("showtime changed: "+id);
        showTimeList.map(showtime => {
            console.log(showtime.showtimeId);
            if(showtime.showtimeId === parseInt(id)){
                console.log("showtime found "+showtime.showtimeId);
                // furthermore, you can set the seat list
                //setSeatList(showtime.seats)
                setShowTime(showtime);
            }
        });
    }
    

    const saveBtn = (e) => {
        e.preventDefault();
        console.log('Theater Selected',theater.theaterName);
        console.log('Movie Selected',movie.movieName);
        console.log('Showtime Selected',showTime.showtimeTime);

    }

    return (
        <div>
          <div className="container-fluid">
            <div className="row">
              <div className="col-sm-4">
                <h2 className="alert alert-warning">Movies</h2>
                
                <br />
                
                <select className="form-control" onChange={handleTheaterChange}>
                  <option value="">Choose theatre</option>
                  {theaterList.map(theater => (
                  <option value={theater.theaterId} key={theater.theaterId}>
                    {theater.theaterName}
                  </option>
                  ))}
                </select>

                  <br/>

                  <select className="form-control"  onChange={handleMovieChange}>
                    <option value="">Choose Movie</option>
                    {movieList.map(movie => (
                      <option value={movie.movieId} key={movie.movieId} >{movie.movieName}</option>
                    ))}
                  </select>

                  <br/>

                  <select className="form-control"  onChange={handleShowTimeChange}>
                    <option value="">Choose showtime</option>
                    {showTimeList.map(showtime => (
                      <option value={showtime.showtimeId} key={showtime.showtimeId} >{showtime.showtimeDate}</option>
                    ))}
                  </select>


                  <button className="btn btn-primary" onClick={saveBtn}>Save</button>
              </div>
            </div>
          </div>      
        </div>
      )
    }
    export default Form

important! change the word 'theatre' to 'theater', or you use either of them, but consistently.