Been trying to figure this out for a couple hours now but I'm stumped. According to the console, when I make a patch request, the request goes through and actually updates the information, but my map function is breaking after that and it renders a blank page.
Here's the component with the error:
import { useState, useEffect } from "react"
// import { EmployeeForm } from "./EmployeeForm"
export function EmployeeTable() {
const [employees, setEmployees] = useState([])
const [employeeId, setEmployeeId] = useState([])
const [update, setUpdate] = useState(false)
const [firstName, setFirstName] = useState('')
const [lastName, setLastName] = useState('')
useEffect(() => {
fetch('/api/employees')
.then(res => res.json())
.then(json => setEmployees(json.employees)
)
}, [])
const updateEmployee = async () => {
try {
const res = await fetch(`/api/employees/${employeeId}`,
{method: 'PATCH', body: JSON.stringify({firstName, lastName})})
const json = await res.json()
const employeesCopy = [...employees]
const index = employees.findIndex((employee) => employee.id === employeeId)
employeesCopy[index] = json.employee
setEmployees(employeesCopy)
setFirstName('')
setLastName('')
setUpdate(false)
setEmployeeId([])
} catch (err) {
console.log(err)
}
}
const submitForm = async (event) => {
event.preventDefault()
if(update){
updateEmployee()
}
}
const deleteEmployee = async (id) => {
try {
await fetch(`/api/employees/${id}`, {method: 'DELETE'})
setEmployees(employees.filter(employee => employee.id !== id))
} catch (error) {
}
}
const setEmployeeToUpdate = (id) => {
const employee = employees.find(emp => emp.id === id)
if(!employee) return
setUpdate(true)
setEmployeeId(employee.id)
setFirstName(employee.firstName)
setLastName(employee.lastName)
}
return (
<div>
<header>
<h1>Employees</h1>
</header>
{employees.length > 0 ? (
<table>
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{employees.map(({id, firstName, lastName}) => {
return(
<tr key={id}>
<td>{firstName}</td>
<td>{lastName}</td>
<td>
<button onClick={() => setEmployeeToUpdate(id)}>UPDATE</button>
<button onClick={() => deleteEmployee(id)}>DELETE</button>
</td>
</tr>
)
})}
</tbody>
</table>
) : (
// If for some reason the employees cannot be returned the page will render this p tag.
<p>No employees</p>
)}
<form onSubmit={submitForm}>
<div>
<div>
<input type="text" value={firstName} onChange={e => setFirstName(e.target.value)}/>
</div>
<div>
<input type="text" value={lastName} onChange={e => setLastName(e.target.value)}/>
</div>
<div>
<button type='submit'>{update ? 'Update' : 'Create'}</button>
</div>
</div>
</form>
</div>
)
}
And here is the MirageJS server.js
import { createServer, Model } from "miragejs";
import faker from "faker";
import avatar from "./avatar.png";
export function makeServer({ environment = "test" } = {}) {
let server = createServer({
environment,
models: {
employee: Model,
},
seeds(server) {
for (let i = 0; i < 10; i++) {
server.create("employee", {
id: faker.datatype.uuid(),
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
email: faker.internet.email(),
phone: faker.phone.phoneNumber(),
bio: faker.lorem.paragraph(),
avatar: avatar,
address: {
streetAddress: `${faker.address.streetAddress()} ${faker.address.streetName()}`,
city: faker.address.city(),
state: faker.address.stateAbbr(),
zipCode: faker.address.zipCode(),
},
});
}
},
routes() {
this.namespace = "api";
this.get(
"/employees",
(schema) => {
return schema.employees.all();
},
{ timing: 1000 }
);
this.patch(
"/employees/:id",
(schema, request) => {
const attrs = JSON.parse(request.requestBody);
const employee = schema.employees.find(request.params.id);
employee.update(attrs);
},
{ timing: 300 }
);
this.delete(
"/employees/:id",
(schema, request) => {
const employee = schema.employees.find(request.params.id);
employee.destroy();
return new Response();
},
{ timing: 300 }
);
},
});
return server;
}
Provide a default value, to destructure from employees.map(({id, firstName, lastName})
.
{employees.filter(item => item).map(({ id = 0, firstName = 'empty', lastName = 'empty' }) => {...
setEmployees((prevState) => {
const index = prevState.findIndex((employee) => employee.id === employeeId);
let newEmployees = […prevState];
newEmployees[index] = json.employee;
return newEmployees;
}))
You miss return
in server.js patch request.
server.js
this.patch(
"/employees/:id",
(schema, request) => {
const attrs = JSON.parse(request.requestBody);
const employee = schema.employees.find(request.params.id);
return employee.update(attrs);
},
{ timing: 300 }
);