Home > Net >  function only adds one element to Favorites Array
function only adds one element to Favorites Array

Time:10-14

I just realized my markFavorite function will only add one element to the favorites array, as soon as I try adding another element it will log:

"FirebaseError: Function updateDoc() called with invalid data. Unsupported field value: undefined (found in document users/l2c8ieJurAfrqI1Pj6wNWro1S2u2)"

I can keep adding that one element without a problem, but as soon as I try to add another element, I get this error.

Here is the function code:

async function markFavorite(did, nombre, comentarios, valor) {
  try {
    const docRef = doc(db, "users", auth.currentUser.uid);
    const docSnap = await getDoc(docRef);
    if (docSnap.exists()) {
      console.log("Document.data:", docSnap.data());
      const favoriteUpdate = {
        favorite: true,
        id: did,
        nombre: nombre,
        comentarios: comentarios,
        valor: valor,
      };
      let favoritesUpdate;
      const favorites = docSnap.data().favorites;
     // Checking if the array is empty or not. If it is empty, it will add the new item to the array.
     // If it is not empty, it will check if the item is already in the array. If it is, it will update
     // the item. If it is not, it will add the new item to the array.
      if (favorites && favorites.length) {
        const findAuto = favorites.find((item) => item.id === did);
        if (findAuto) {
          favoritesUpdate = favorites.map((item) =>
            item.id === did ? favoriteUpdate : item
          );
        } else {
          // Adding the new item to the array.
          favoritesUpdate = [...favorites, favoritesUpdate];
        }
      } else {
       // Adding the new item to the array.
        favoritesUpdate = [favoriteUpdate];
      }

      // Updating the document with the new array.
      await updateDoc(docRef, {
        favorites: favoritesUpdate,
      });
      alert("¡Añadido a tus favoritos!");
    } else {
      console.log("No se localiza este documento!");
    }
  } catch (error) {
    console.log(error);
  }
}

If anybody has a suggestion as to where the problem lies, I would very much appreciate it.

CodePudding user response:

Most likely your function is not getting all arguments it expects.

You have few solutions:

  • If functions arguments are all required, then wrap your function content in:

    if(!did && !nombre && !comentarios && !valor){
        // Your function code here   } else {
        console.log('Missing markFavorite function arguments', {...arguments};
        // Could also throw error: throw new Error['Missing arguments']   } } ```
    
    
  • Otherwise, if you are ok with these values being empty you can set default values in case arguments are empty:

    async function markFavorite(did = '', nombre = null, comentarios = {}, valor = '') { 
       // Your function code here 
    } 
    

    Obviously set the default values to match your data model/schema.

  • You can also tell Firestore to ignore undefined values, as in not write properties with undefined to Firestore, but this should probably be last resort option, as then your data model/schema will not be consistent.

    Here are data types that work with Firestore

    You would have to initialize firestore like this, with ignoreUndefinedProperties option:

    import { initializeFirestore } from "firebase/firestore"
    
    const db = initializeFirestore( app, { ignoreUndefinedProperties: true })
    

CodePudding user response:

I managed to replicate your error message. We are getting this kind of error because favoritesUpdate declaration doesn't contain any values that's why favoritesUpdate = [...favorites, favoritesUpdate] is returned as undefined. One way to fix this, you can use the Firestore provided method arrayUnion() as it adds elements to an array but only elements not already present. Your first else statement should be like this:

else {
          // Adding the new item to the array.
          favoritesUpdate = arrayUnion(favoriteUpdate);
        }

You can check this documentation on updating elements in an array.

Here's a sample working code for your reference:

async function markFavorite(did, nombre, comentarios, valor) {
    try {
      const docRef = doc(db, "users", auth.currentUser.uid);
      const docSnap = await getDoc(docRef);
      if (docSnap.exists()) {
        console.log("Document.data:", docSnap.data());
        const favoriteUpdate = {
          favorite: true,
          id: did,
          nombre: nombre,
          comentarios: comentarios,
          valor: valor,
        };
        let favoritesUpdate;
        const favorites = docSnap.data().favorites;
       // Checking if the array is empty or not. If it is empty, it will add the new item to the array.
       // If it is not empty, it will check if the item is already in the array. If it is, it will update
       // the item. If it is not, it will add the new item to the array.
        if (favorites && favorites.length) {
          const findAuto = favorites.find((item) => item.id === did);
          if (findAuto) {
            favoritesUpdate = favorites.map((item) =>
              item.id === did ? favoriteUpdate : item
            );
          } else {
            // Adding the new item to the array.
            favoritesUpdate = arrayUnion(favoriteUpdate); //--> This is the one I changed
          }
        } else {
         // You can also use arrayUnion here if there's no data on the document. This will produce the same result.
         // favoritesUpdate = arrayUnion(favoriteUpdate);
         // Adding the new item to the array.
          favoritesUpdate = [favoriteUpdate];
        }
  
        // Updating the document with the new array.
        await updateDoc(docRef, {
          favorites: favoritesUpdate,
        });
        console.log("¡Añadido a tus favoritos!");
      } else {
        console.log("No se localiza este documento!");
      }
    } catch (error) {
      console.log(error);
    }
  }
  • Related