Reputation: 35
so i have the problem where i have the form a phonebook and i add people in it but the task is whenever i try add the user that is already in there it must not let me do it and throw an error this person is already in a phonebook i dont want only solution i want explanation if anyone can explain it to me how to solve it and how it works code:
import React, { useState } from 'react'
import Person from './Person'
const App = () => {
const [persons, setPersons] = useState([
])
const [newName, setNewName] = useState('')
const handleNoteChange = (event) => {
setNewName(event.target.value)
}
const resetForm = () => {
setNewName('')
}
const handleSubmit = (e) => {
e.preventDefault()
const persona = {
name: newName,
id:Math.floor(Math.random() * 10000)
}
setPersons(persons.concat(persona))
setNewName('')
persons.map(perperson =>{
if(perperson.name === newName){
alert(`${newName} is already in the phonebook `)
}
})
console.log(persona);
}
return (
<div>
<h2>Phonebook</h2>
<form onSubmit={handleSubmit}>
<div>
name: <input
value={newName}
onChange={handleNoteChange}
/>
</div>
<div>
<button type="submit">add</button>
</div>
</form>
<h2>Numbers</h2>
<ul>
{persons.map(person => {
return(
<Person key={person.id} name={person.name} />
)
})}
</ul>
<p onClick={resetForm}>reset input</p>
<p>phonebook name is - {newName}</p>
</div>
)
}
export default App
Person component:
import React from 'react';
const Person = (props) => {
return(
<div>
<li key ={props.id}>{props.name}</li>
</div>
)
};
export default Person;
Upvotes: 0
Views: 1045
Reputation: 397
You should implement your validation logic before inserting the person in the array, right now your code is performing the validation after you've inserted the person, hence it will never avoid a repeated entry.
const handleSubmit = (e) => {
e.preventDefault()
const persona = {
name: newName,
id:Math.floor(Math.random() * 10000)
}
//Here you are inserting the person into the persons array and setting the newName to '',
//that won't allow you to use newName later in order to perform any kind
//of validation. You should set newName to '' once you've already validated if the
//provided user is part of the array.
setPersons(persons.concat(persona))
setNewName('')
//Here you are validating if the person is already part of the array
//You should do this before the insertion process.
persons.map(perperson =>{
if(perperson.name === newName){
alert(`${newName} is already in the phonebook `)
}
})
Also, there's no need to use map
in order to perform the validation process, since map
iterates over the array and return the elements that meet the specified condition (that won't help you in this particular case). You should use the some
method instead, and keep the same validation logic; return true if an element meets the expected condition and false otherwise, that will allow you to check if indeed, the element you're trying to insert is already part of the array. You'll end up with the following result:
const handleSubmit = (e) => {
e.preventDefault()
const persona = {
name: newName,
id:Math.floor(Math.random() * 10000)
}
let alredyInRegister = persons.some(perperson =>{
if(perperson.name === newName){
return true;
}
return false
})
if (alreadyInRegister) {
alert(`${newName} is already in the phonebook `)
} else {
setPersons(persons.concat(persona))
setNewName('')
}
}
Upvotes: 1
Reputation: 2217
On submit function, you need to first check whether the value is already there or not. only after checking push it to the original array. in your current method you are pushing the name before validation check. check the comments in code for more explanation
import React, { useState } from "react";
import Person from "./Person";
const App = () => {
const [persons, setPersons] = useState([]);
const [newName, setNewName] = useState("");
const handleNoteChange = (event) => {
setNewName(event.target.value);
};
const resetForm = () => {
setNewName("");
};
const handleSubmit = (e) => {
e.preventDefault();
//checking is the value already there in persons, if index return -1
//it means value is not there on the array and we can push newName to
//array, if it return a value other than -1 it means the value already there in a index.
if (persons.findIndex((p) => p.name == newName) != -1) {
alert(`${newName} is already in the phonebook `);
return; //This will stop further execution if function so that it will not push data
}
const persona = {
name: newName,
id: Math.floor(Math.random() * 10000)
};
setPersons([...persons, persona]); //contacting array using spread opertaor
setNewName("");
};
return (
<div>
<h2>Phonebook</h2>
<form onSubmit={handleSubmit}>
<div>
name: <input value={newName} onChange={handleNoteChange} />
</div>
<div>
<button type="submit">add</button>
</div>
</form>
<h2>Numbers</h2>
<ul>
{persons.map((person) => {
return <Person key={person.id} name={person.name} />;
})}
</ul>
<p onClick={resetForm}>reset input</p>
<p>phonebook name is - {newName}</p>
</div>
);
};
export default App;
Here is working demo https://codesandbox.io/s/stoic-hofstadter-f402o?file=/src/App.js
Upvotes: 1