Home > other >  Array pushes elements already in Array despite !arry.includes
Array pushes elements already in Array despite !arry.includes

Time:01-08

I am trying to build an app that requires a directory. Every time I update the component, it pushes the data into the array again creating multiple copies. I tried solving that by adding an !arry.includes, but that does not stop it for adding another occurrence of the data.

 const Directory = () => {
  const [searchResults, setSearchResults] = useState([]);
  const [loading, setLoading] = useState(false);
  const { currentUser } = useContext(AuthContext);

  useEffect(() => {
    setLoading(true);
    const data = async () => {
      const q = query(collection(db, "users"), where("type", "==", "doctor"));
      const querySnapshot = await getDocs(q);
      querySnapshot.forEach((doc) => {
        const data = doc.data();
        if (!searchResults.includes(data)) {
          searchResults.push(data);
        }
      });
      setLoading(false);
    };
    data();
  },[]);
  console.log(searchResults);

CodePudding user response:

It appears that you are trying to compare objects here which doesn't work with the array.includes() method.

In javascript

const user1 = {name : "nerd", org: "dev"};
const user2 = {name : "nerd", org: "dev"};
user1 == user2; // is false

You would need to search for something more specific or try Comparing Objects. Either way what your trying to do is tricky and you may need to explore lodash or something to solve it

CodePudding user response:

It looks like you are trying to avoid adding duplicate entries to the searchResults array, but the code you provided will not achieve that.

The problem is that you are modifying the searchResults array directly in the loop, rather than creating a new array and setting it as the new value of searchResults.

One way to fix this would be to create a new array inside the loop and push the data to it, then set the new array as the value of searchResults after the loop. Here is how the code would look:

const Directory = () => {
  const [searchResults, setSearchResults] = useState([]);
  const [loading, setLoading] = useState(false);
  const { currentUser } = useContext(AuthContext);

  useEffect(() => {
    setLoading(true);
    const data = async () => {
      const q = query(collection(db, "users"), where("type", "==", "doctor"));
      const querySnapshot = await getDocs(q);
      // Create a new array to hold the data
      const newSearchResults = [];
      querySnapshot.forEach((doc) => {
        const data = doc.data();
        // Push the data to the new array if it's not already in searchResults
        if (!searchResults.includes(data)) {
          newSearchResults.push(data);
        }
      });
      // Set the new array as the value of searchResults
      setSearchResults(newSearchResults);
      setLoading(false);
    };
    data();
  },[]);
  console.log(searchResults);
};
  • Related