My app is working fine and I can refresh other pages. But when I refresh the page where an event is being edited (EditEvent Component) it gives me this error message: Uncaught TypeError: Cannot read properties of undefined (reading ‘name’). And I’ve noticed that all my state variables are “undefined” after the refresh, even at the top level(App.js). Can someone please help?
App.js
import React from "react";
import { Routes, Route } from 'react-router-dom';
import { useState, useEffect } from "react";
import Home from "./components/Home";
import SignUp from "./components/SignUp";
import Login from "./components/Login";
import EditEvent from "./components/EditEvent";
import NewEvent from "./components/NewEvent";
function App() {
const [currentUser, setCurrentUser] = useState("");
const [events, setEvents] = useState([])
const [clients, setClients] = useState([])
useEffect(() => {
fetch('/auth')
.then(r => {
if(r.ok){
r.json().then(user => {
setCurrentUser(user)
setClients(user.clients)
}
)
}
})
},[])
useEffect(() => {
fetch('/events')
.then(r => {
if(r.ok){
r.json().then(events => setEvents(events)
)
}
})
},[])
function handleLogin(user) {
setCurrentUser(user)
}
function handleSetUser(user) {
setCurrentUser(user)
}
function handleEditEvent(editedEvent) {
const unchangedEvents = events.filter(event => event.id !== editedEvent.id)
setEvents([...unchangedEvents,editedEvent])
}
function handleDeleteEvent(deletedEvent){
const updatedEvents = events.filter((event) => event.id !== deletedEvent.id)
setEvents([...updatedEvents])
}
function handleNewEvent(newEvent) {
setEvents([...events,newEvent])
}
console.log(events)
return (
<div className="App">
<Routes>
<Route path="/home" element ={<Home currentUser={currentUser} setCurrentUser={setCurrentUser} events={events} clients={clients} onEventDelete={handleDeleteEvent} addEvent={handleNewEvent}/>} />
<Route path="/" element={<Login onLogin={handleLogin}/>} />
<Route path="/signup" element={<SignUp setUser={handleSetUser}/>} />
<Route path="/events/:id" element={<EditEvent events={events} clients={clients} onEditEvent={handleEditEvent} />} />
<Route path="/newevent" element={<NewEvent events={events} clients={clients} addEvent={handleNewEvent}/>} />
</Routes>
</div>
);
}
export default App;
Home.js
import React from 'react';
import NavBar from './NavBar';
import Events from './Events';
import Vendors from './Vendors';
import { useState } from "react"
import NewEvent from './NewEvent';
function Home({ currentUser, setCurrentUser, events, clients, onEventDelete, addEvent }) {
const [active, setActive] = useState('Events')
return (
<div>
<NavBar currentUser={currentUser} setCurrentUser={setCurrentUser} setActive = {setActive}/>
{active === "Events" && <Events events={events} clients={clients} onEventDelete={onEventDelete} />}
{active === "Vendors" && <Vendors />}
{active === "NewEvent" && <NewEvent clients={clients} addEvent={addEvent} currentUser={currentUser} setActive={'Events'}/>}
</div>
);
}
export default Home;
Events.js
import React from "react";
import EventCard from "./EventCard";
import "../Container.css";
function Events ( { events, onEventDelete } ) {
const renderEvents = events.sort( (a,b) => a.id > b.id ? 1 : -1).map((event) => ( <EventCard key={event.id} event={event} onEventDelete={onEventDelete}/> ))
return (
<section className="twitter">
<h1 className="header">Upcoming Events</h1>
<div className="container">
{renderEvents}
</div>
</section>
)
}
export default Events;
EventCard.js
import React from 'react';
import { useNavigate } from 'react-router-dom'
import "../Container.css";
function EventCard( { event, onEventDelete }) {
const navigate = useNavigate();
function handleEventDelete() {
fetch(`/events/${event.id}`, {
method: 'DELETE'
})
.then(()=> {
onEventDelete(event)
});
}
function getTime(eventTime) {
const time = eventTime.split('T')[1];
const hour = time.split(':')[0];
const minutes = time.split(':')[1];
let timeValue = '';
if (hour > 0 && hour <= 12) {
timeValue= "" + hour
} else if (hour > 12) {
timeValue= "" + (hour - 12);
} else if (hour === 0) {
timeValue= "12"
}
const standardTime = timeValue + ':' + minutes;
const dayNight = timeValue = (hour >= 12) ? " P.M." : " A.M.";
return standardTime + dayNight;
}
function handleEdit(e) {
e.preventDefault()
navigate(`/events/${event.id}`)
}
return ( <div className='card' >
<h1 className='title'>{event.name}</h1>
<p>Client: {event.client.name}</p>
<p>Date: {event.start_date}</p>
<p>Time: {getTime(event.start_time)}</p>
<p>Location: {event.location}</p>
<p>Description: {event.description}</p>
<br></br>
<ul>
Vendors:
{event.vendors.map((vendor) =>
<li key={vendor.id}>{vendor.name}</li>)}
</ul>
<button id='edit-button' onClick={handleEdit} >Edit</button >
<button id='delete-button' onClick={handleEventDelete}>Delete Event</button>
</div>)
}
export default EventCard;
EditEvent.js
import React from 'react'
import { useState } from "react";
import { Link, useNavigate, useParams} from "react-router-dom";
import "../index.css"
function EditEvent ( { events, onEditEvent, clients } ) {
const params = useParams();
const event = events.find((event) => event.id == params.id)
const navigate = useNavigate();
const [name, setName] = useState(event.name);
const [description, setDescription] = useState(event.description);
const [location, setLocation] = useState(event.location);
const [budget, setBudget] = useState(event.budget);
const [currentCost, setCurrentCost] = useState(event.current_cost);
const [startDate, setStartDate] = useState(event.start_date);
const [startTime, setStartTime] = useState(getTime(event.start_time));
const [endDate, setEndDate] = useState(event.end_date);
const [endTime, setEndTime] = useState(event.end_time);
const [selectedClient, setSelectedClient] = useState(event.client.name)
function getTime(eventTime) {
const time = eventTime.split('T')[1];
const hour = time.split(':')[0];
const minutes = time.split(':')[1];
let timeValue = '';
if (hour > 0 && hour <= 12) {
timeValue= "" + hour
} else if (hour > 12) {
timeValue= "" + (hour - 12);
} else if (hour == 0) {
timeValue= "12"
}
const standardTime = timeValue + ':' + minutes;
const dayNight = timeValue = (hour >= 12) ? " P.M." : " A.M.";
return standardTime + dayNight;
}
function handleClientChange(e) {
setSelectedClient(e.target.value)
}
function handleSubmitChanges(e) {
e.preventDefault()
const client = clients.find((client) => client.name == selectedClient)
const editedEvent = {
name: name,
description: description,
start_date: startDate,
start_time: startTime,
end_date: endDate,
end_time: endTime,
locaiton: location,
budget: budget,
current_cost: currentCost,
id: event.id,
client_id: client.id,
}
fetch(`/events/${editedEvent.id}`, {
method: 'PATCH',
headers: {
'Content-Type' : 'application/json'
},
body: JSON.stringify(editedEvent)
})
.then(r => r.json())
.then(editedEvent => {
onEditEvent(editedEvent)
navigate("/home")
})
}
console.log(selectedClient)
return event ? (
<div className='edit-background'>
<form className="edit-form" onSubmit={handleSubmitChanges}>
<div className="edit-title">Edit Event</div>
<div className="input-container ic0">
<input id="name" className="input" type="text" defaultValue={name} onChange={(e) => setName(e.target.value)}/>
<label className="edit-cut edit-cut-short">Name</label>
</div>
<div className="input-container ic0">
<input id="desc" className="input" type="text" defaultValue={description} onChange={(e) => setDescription(e.target.value)}/>
<label className="edit-cut edit-cut-short">Description</label>
</div>
<div className="input-container ic0">
<input id="start-date" className="input" type="text" defaultValue={startDate} onChange={(e) => setStartDate(e.target.value)}/>
<label className="edit-cut edit-cut-short">Start Date</label>
</div>
<div className="input-container ic0">
<input id="start-time" className="input" type="text" defaultValue={startTime} onChange={(e) => setStartTime(e.target.value)}/>
<label className="edit-cut edit-cut-short">Start Time</label>
</div>
<div className="input-container ic0">
<input id="end-date" className="input" type="text" defaultValue={endDate} onChange={(e) => setEndDate(e.target.value)}/>
<label className="edit-cut edit-cut-short">End Date</label>
</div>
<div className="input-container ic0">
<input id="end-time" className="input" type="text" defaultValue={endTime} onChange={(e) => setEndTime(e.target.value)}/>
<label className="edit-cut edit-cut-short">End Time</label>
</div>
<div className="input-container ic0">
<input id="location" className="input" type="text" defaultValue={location} onChange={(e) => setLocation(e.target.value)}/>
<label className="edit-cut edit-cut-short">Location</label>
</div>
<div className="input-container ic0">
<input id="budget" className="input" type="text" defaultValue={budget} onChange={(e) => setBudget(e.target.value)}/>
<label className="edit-cut edit-cut-short">Budget</label>
</div>
<div className="input-container ic0">
<input id="current-cost" className="input" type="integer" defaultValue={currentCost} onChange={(e) => setCurrentCost(e.target.value)}/>
<label className="edit-cut edit-cut-short">Current Cost</label>
</div>
<select value={selectedClient} onChange={handleClientChange}>
{clients.map((client) => <option key={client.id}>{client.name}</option>)}
</select>
<button type="submit" className="submit">Edit</button>
<Link to={"/home"}>
<button id='submit'>Cancel</button >
</ Link>
</form>
</div>
) : null
};
export default EditEvent;
NavBar.js
import React from "react";
import "../NavBar.css";
import { useNavigate } from 'react-router-dom';
function NavBar( {currentUser, setCurrentUser, setActive } ) {
const navigate = useNavigate()
function handleLogOut() {
navigate('/')
fetch('/logout',{method: "DELETE"}).then((r) => {
if(r.ok){
setCurrentUser(null)
}
})
};
return (
<main className="main">
<aside className="sidebar">
<p className="greeting">Hello {currentUser.first_name}</p>
<nav className="nav">
<button className="nav-button" onClick={() => setActive("NewEvent")}>New Event</button>
<button className="nav-button" onClick={() => setActive("Events")}>Events</button>
<button className="nav-button" onClick={() => setActive("Vendors")}>Vendors</button>
<button className="nav-button" onClick={handleLogOut}>Logout</button>
</nav>
</aside>
</main>
)
}
export default NavBar;