dortax
dortax

Reputation: 35

how to not add a user if it exists in a form react.js

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

Answers (2)

jmj0502
jmj0502

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

Sojin Antony
Sojin Antony

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

Related Questions