Search code examples
javascriptreactjsalertmap-function

Checking value in array by map function and also displaying alert box just once


import React, { useState, useEffect } from 'react';
import './Login.css';
import { Link, useHistory } from 'react-router-dom';
import axios from 'axios';

function Login() {

    var history = useHistory()
    const [data, setData] = useState([])
    const [user, setUser] = useState({
        email: "",
        password: ""
    });

    const onEmailChange = e => {
        setUser({ ...user, [e.target.name]: e.target.value });
    };
    const onPasswordChange = e => {
        setUser({ ...user, [e.target.name]: e.target.value });
    };

    useEffect(() => {
        getUsers()
    }, [])
    const getUsers = async () => {
        try {
            const Data = await axios.get(`http://localhost:3003/users`)
            setData(Data.data)
        } catch (error) {
            alert(`please wait! ${error}`)
        }
    }

    const checkEmail = () => {
        data.map(d => {
            if(user.email === d.email){
                return(history.push('/home')
            }
            else{
                return(alert(`User does not exist!`))
            }
        })

    }

    const onSubmit = e => {
        e.preventDefault();
        checkEmail()

    };



    return (
        <div className="container">
            <div className="w-75 mx-auto shadow p-5">
                <h2 className="text-center mb-4">Add A User</h2>
                <form onSubmit={e => onSubmit(e)}>
                    <div className="form-group">
                        <input
                            type="email"
                            className="form-control form-control-lg"
                            placeholder="Enter Your E-mail Address"
                            name="email"
                            onChange={e => onEmailChange(e)}
                        />
                    </div>
                    <div className="form-group">
                        <input
                            type="password"
                            className="form-control form-control-lg"
                            placeholder="Enter Your password"
                            name="password"
                            onChange={e => onPasswordChange(e)}
                        />
                    </div>
                    <button className="btn btn-primary btn-block">Login</button>
                </form>
            </div>
        </div>
    )
}

export default Login

This code is not working well, I want to show the alert box just once but it shows according to the number of objects in Array. I want that it checks all array values at once by map function and give a response either use history or alert box. But it displays an alert box for those values which do not match and then runs useHistory for which the value match.


Solution

  • Issue

    It seems you are rather wanting to search the data state for a matching email and either navigate if it's found, or pop up the alert if it isn't. This is not what Array.prototype.map is for. Mapping is for mapping a source array to a new array of equal length. What your code does does is it tries to navigate or alert for every element in the source array.

    Solution

    Use Array.prototype.some to search through the data array for some element that matches the condition, and conditionally navigate or display an alert.

    const checkEmail = () => {
      const hasEmailMatch = data.some(d => user.email === d.email);
      if (hasEmailMatch) {
        history.push('/home');
      }
      alert(`User does not exist!`);
    }