User2000
User2000

Reputation: 129

Uncaught TypeError: Cannot read properties of undefined (reading 'state')

I am trying to create a new flight and display the values of its attributes in the console and return to the home page immediately after submitting. However, when I run the server, this error shows up(I am using react-router-dom v6):

TypeError: Cannot read properties of undefined (reading 'state') onSubmit

Here's the code of CreateFlight component:

import React, { Component } from 'react';
import { Container } from 'react-bootstrap';
import DatePicker from 'react-datepicker';
import "react-datepicker/dist/react-datepicker.css";


export class CreateFlight extends Component {
    constructor(props) {
        super(props);

        this.onChangeFrom = this.onChangeFrom.bind(this);
        this.onChangeTo = this.onChangeTo.bind(this);
        this.onChangeCabin = this.onChangeCabin.bind(this);
        this.onChangeSeatNumber = this.onChangeSeatNumber.bind(this);
        this.onChangeFlightDate = this.onChangeFlightDate.bind(this);
        this.onChangeDepartureTime = this.onChangeDepartureTime.bind(this);
        this.onChangeArrivalTime = this.onChangeArrivalTime.bind(this);
        this.onChangeTerminal = this.onChangeTerminal.bind(this);

        this.state = {
            from: '',
            to: '',
            cabin: '',
            seatNumber: 0,
            flightDate: new Date(),
            departureTime: '',
            arrivalTime: '',
            terminal: 0,

        }
    }


    onChangeFrom(e) {
        this.setState({
            from: e.target.value
        });
    }

    onChangeTo(e) {
        this.setState({
            to: e.target.value
        });
    }

    onChangeCabin(e) {
        this.setState({
            cabin: e.target.value
        });
    }

    onChangeSeatNumber(e) {
        this.setState({
            seatNumber: e.target.value
        });
    }

    onChangeFlightDate(date) {
        this.setState({
            flightDate: date
        });
    }

    onChangeDepartureTime(e) {
        this.setState({
            departureTime: e.target.value
        });
    }

    onChangeArrivalTime(e) {
        this.setState({
            arrivalTime: e.target.value
        });
    }

    onChangeTerminal(e) {
        this.setState({
            terminal: e.target.value
        });
    }

    onSubmit(e) {
        e.preventDefault();

        const flight = {
            from: this.state.from,
            to: this.state.to,
            cabin: this.state.cabin,
            seatNumber: this.state.seatNumber,
            flightDate: this.state.flightDate,
            departureTime: this.state.departureTime,
            arrivalTime: this.state.arrivalTime,
            terminal: this.state.terminal

        }

        console.log(flight)

        window.location = '/home';
    }
    render() {
        return (
            <Container>
                <div><br/>
                    <h3>Create New Flight </h3>
                    <form onSubmit={this.onSubmit}>
                        <div className="form-group">
                            <label>From: </label>
                            <input type="text"
                                required
                                className="form-control"
                                placeholder="Enter departure city"
                                value={this.state.from}
                                onChange={this.onChangeFrom}
                            />
                        </div>
                        <div className="form-group">
                            <label>To: </label>
                            <input type="text"
                                required
                                className="form-control"
                                placeholder="Enter destination city"
                                value={this.state.to}
                                onChange={this.onChangeTo}
                            />
                        </div>
                        <div className="form-group">
                            <label>Cabin: </label>
                            <input type="text"
                                required
                                className="form-control"
                                placeholder="Choose cabin class"
                                value={this.state.cabin}
                                onChange={this.onChangeCabin}
                            />
                        </div>
                        <div className="form-group">
                            <label>Seat Number: </label>
                            <input type="text"
                                required
                                className="form-control"
                                placeholder="Choose seat number"
                                value={this.state.seatNumber}
                                onChange={this.onChangeSeatNumber}
                            />
                        </div>
                        <div className="form-group">
                            <label>Flight Date: </label>
                            <div>
                                <DatePicker
                                    selected={this.state.flightDate}
                                    onChange={this.onChangeFlightDate}
                                />
                            </div>
                        </div>
                        <div className="form-group">
                            <label>Departure Time: </label>
                            <input type="text"
                                required
                                className="form-control"
                                placeholder="Enter departure time"
                                value={this.state.departureTime}
                                onChange={this.onChangeDepartureTime}
                            />
                        </div>
                        <div className="form-group">
                            <label>Arrival Time: </label>
                            <input type="text"
                                required
                                className="form-control"
                                placeholder="Enter arrival time"
                                value={this.state.arrivalTime}
                                onChange={this.onChangeArrivalTime}
                            />
                        </div>
                        <div className="form-group">
                            <label>Terminal: </label>
                            <input type="text"
                                required
                                className="form-control"
                                placeholder="Choose terminal number"
                                value={this.state.terminal}
                                onChange={this.onChangeTerminal}
                            />
                        </div><br/>

                        <div className="form-group">
                            <input type="submit" value="Create Flight" className="btn btn-primary" />
                        </div>
                    </form>
                </div>
            </Container>
        )
    }
}

And here's the code of App component which renders CreateFlight component:



import './App.css';
import {Home} from './components/Home';
import {AvailableFlights} from './components/AvailableFlights';
import {FlightsSchedule} from './components/FlightsSchedule';
import {CreateFlight} from './components/CreateFlight';
import {Login} from './components/Login';
import {FindFlight} from './components/FindFlight';
import {Footer} from './components/Footer';
import {BrowserRouter, Route, Routes} from 'react-router-dom';
import { NavDropdown, Container, Navbar, Nav, Form, Button, FormControl} from "react-bootstrap";
import 'bootstrap/dist/css/bootstrap.min.css';





function App() {
  return (
    <BrowserRouter>
    <Navbar bg="dark" expand="lg" variant="dark" sticky="top" >
    <Container fluid>
      <Navbar.Brand id="nav_title" href="/home">Airline Reservation</Navbar.Brand>
      <Navbar.Toggle aria-controls="navbarScroll" />
      <Navbar.Collapse id="navbarScroll">
        <Nav
          className="me-auto my-2 my-lg-0"
          style={{ maxHeight: '100px' }}
          navbarScroll
        >
          <Nav.Link href="/home">Home</Nav.Link>
          <Nav.Link href="/login">Login</Nav.Link>
          <NavDropdown title="Flights" id="navbarScrollingDropdown">
            <NavDropdown.Item href="/availableFlights">Available Flights</NavDropdown.Item>
            <NavDropdown.Item href="/flightsSchedule">Flights Schedule</NavDropdown.Item>
            <NavDropdown.Item href="/createFlight">Create Flight</NavDropdown.Item>
            {/* <NavDropdown.Divider /> */}
            {/* <NavDropdown.Item href="#action5">
              Something else here
            </NavDropdown.Item> */}
          </NavDropdown>
        </Nav>
        <Form className="d-flex">
          <FormControl
            type="search"
            placeholder="Search"
            className="me-2"
            aria-label="Search"
          />
          <Button variant="outline-success">Search</Button>
        </Form>
      </Navbar.Collapse>
    </Container>
  </Navbar>
       <Routes>
         <Route path='/home' element={<Home />}/>
         <Route path='/login' element={<Login />}/>
         <Route path='/availableFlights' element={<AvailableFlights />}/>
         <Route path="/flightsSchedule" element={<FlightsSchedule />}/>
         <Route path='/createFlight' element={<CreateFlight />}/>
         <Route path='/findFlight' element={<FindFlight />}/>   
       </Routes>
       <Footer />
  </BrowserRouter>
  );
}

export default App;

Upvotes: 0

Views: 3456

Answers (1)

Saeed Hemmati
Saeed Hemmati

Reputation: 515

You should bind this for onSubmit method in the constructor.


this.onSubmit = this.onSubmit.bind(this);

Recommendation: You can use functional components with hooks for improving your speed and maintenance of codes in feature.

Upvotes: 0

Related Questions