Reputation: 129
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
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