Home > Blockchain >  Duplicate object going into an array React.js, Firestore
Duplicate object going into an array React.js, Firestore

Time:08-04

First of all the goal is to display cars from a database on a React website, sounds simple enough, right?

I have a Firestore database that has cars in it, it looks like this: enter image description here

I also have a useState hook that looks like this:

   type car = {
    carId: string;
    model: string;
    image: string;
  };
  const [cars, setCars]: [Array<car>, any] = React.useState([]); // update

I am getting data from the Firestore database and all is going well, except that cars from the database get added to the cars hook even though I am checking if it already exists:

  React.useEffect(() => {
    // Get cars from firestore database and set them with setCars
    (async () => {
      const querySnapshot = await getDocs(collection(db, "cars"));
      querySnapshot.forEach((doc) => {
        // Check if car is already in the array
        for (let i = 0; i < cars.length; i  ) {
          if (cars[i].carId === doc.data().carId) {
            console.log("Car already in array");
            return;
          }
        }
        console.table(doc.data());
        setCars((cars: any) => [...cars, doc.data()]);
      });
    })();
  }, []);

In the end cars useState will still end up looking like this: enter image description here

Any help/tips much appreciated!

CodePudding user response:

You can try the following way to check if the element already exists and see if the problem still persists.

const documentData = doc.data();
const newArray = cars.filter(const car => car.carId === documentData.carId)
if(newArray.length > 0) return;
setCars(previousCars => [...previousCars, documentData]);

CodePudding user response:

The return inside your if condition breaks from the immediate for loop, meaning when it compares the first record, it matches and since item exists, that for loop breaks and the program continues on to add the car data.

What you want instead, is to simply check if the new doc.data() exists in your cars list, which you could do by:

querySnapshot.forEach((doc) => {
        // Check if car is already in the array
        if(!cars.find(carItem => carItem.carId === doc.data().carId){
           console.table(doc.data());
           setCars((cars: any) => [...cars, doc.data()]);
        }
      });
  • Related