I have this app that adds “persons” to a “phonebook”, and the user can update the person’s phone if the person already exists. but I want to know to handle the problem of when the person was already deleted (i open two tabs and delete a phone in one tab, and I try to “update” it in the second tab)
I have a persons.js
which handles all HTTP requests (I’m using axios)
and a PersonNotification.js
which tell the user if the phone is “added” or “updated” or “doesn’t exist anymore”
and all the main functionalities are inside the App.js
here is my code
persons.js
import axios from "axios"; const URL = "http://localhost:3001/persons"; const getPersons = () => { return axios.get(URL).then((res) => res.data); }; const addPerson = (person) => axios.post(URL, person); // this is where i have the probelm (i think) const updatePerson = (person, number, setErrMsg) => { axios .put(`${URL}/${person[0].id}`, { name: person[0].name, number, }) //i wanted the change the state of the App.js from this line after there is an error .catch((err) => setErrMsg("err")); }; const deletePerson = (person) => axios.delete(`${URL}/${person.id}`); export { getPersons, addPerson, deletePerson, updatePerson };
App.js
import React, { useState, useEffect } from "react"; import { getPersons, addPerson, deletePerson, updatePerson, } from "./services/persons"; import Filter from "./components/Filter"; import Form from "./components/Form"; import Phonebook from "./components/Phonebook"; import PersonNotification from "./components/PersonNotification"; const App = () => { const [persons, setPersons] = useState([]); const [newName, setNewName] = useState(""); const [newNumber, setNewNumber] = useState(""); const [query, setQuery] = useState(""); const [searchValue, setSearchValue] = useState([]); const [notification, setNotification] = useState(""); const [errMsg, setErrMsg] = useState(""); // fetching the data from json-server (i,e: db.json) useEffect(() => { getPersons().then((res) => setPersons(res)); }, []); // function that fires after the submit const personsAdder = (e) => { e.preventDefault(); const personsObject = { name: newName, number: newNumber }; //checking if the name exists const nameChecker = persons.filter( (person) => person.name === personsObject.name ); console.log(errMsg); if (nameChecker.length > 0) { const X = window.confirm( `${personsObject.name} already exists do you want to update the number` ); if (X === true) { // updating the number if the user confirmed updatePerson(nameChecker, newNumber, setErrMsg); const personsCopy = persons; const index = personsCopy.indexOf(nameChecker[0]); personsCopy[index] = { id: personsCopy[index].id, name: personsCopy[index].name, number: newNumber, }; setPersons([...personsCopy]); setNewName(""); setNewNumber(""); //the function the shows the notification for 5 seconds after the content was updated const notificationSetter = () => { let X = ""; if (errMsg.length > 0) { X = `you can't update${nameChecker[0].name} because it doesn't exist anymore`; } else { X = `${nameChecker[0].name} was updated`; } setNotification(X); setTimeout(() => { setNotification(""); setErrMsg(""); }, 5000); }; notificationSetter(); } } else { //adding a new user if the name was not already in the phonebook setPersons(persons.concat(personsObject)); addPerson(personsObject); setNewName(""); setNewNumber(""); //the function the shows the notification for 5 seconds after the content was added const notificationSetter = () => { setNotification(`${personsObject.name} was added`); setTimeout(() => { setNotification(""); }, 5000); }; notificationSetter(); } }; //... there is still more down here; i don't know if i should copy paste all my code
PersonNotification.js
import React from "react"; import "./PersonNotification.css"; const PersonNotification = ({ notification, errMsg }) => { if (errMsg.length > 0) { return <h1 className="err">{notification}</h1>; } if (notification.length === 0) { return <></>; } else { return <h1 className="notification">{notification}</h1>; } }; export default PersonNotification;
PS: this the github folder of this app. this is an exercise from fullstackopen.com so i hesitate a bit before posting my question here, but i spent more than 4 hours on this problem all i want is to figure out how to update the state of “errMsg” earlier, and i think after that everything will become easy
Advertisement
Answer
This part should help you enough to go further.
persons.js
const updatePerson = (person, number) => { const request = axios .put(`${URL}/${person[0].id}`, { name: person[0].name, number, }); return request.then(response => response.data) };
App.js
if (X === true) { const notificationSetter = (X) => { setNotification(X); setTimeout(() => { setNotification(""); setErrMsg(""); }, 5000); }; // updating the number if the user confirmed updatePerson(nameChecker, newNumber, setErrMsg) .then(data => { notificationSetter(`${nameChecker[0].name} was updated`); console.log('persons :>> ', persons); console.log('data :>> ', data); const personsCopy = persons; const index = personsCopy.indexOf(nameChecker[0]); personsCopy[index] = { id: personsCopy[index].id, name: personsCopy[index].name, number: newNumber, }; setPersons([...personsCopy]); }) .catch(error => { notificationSetter(`you can't update ${nameChecker[0].name} because it doesn't exist anymore`); getPersons().then((res) => setPersons(res)); }) setNewName(""); setNewNumber(""); }