Search code examples
javascriptreactjsfirebasegoogle-cloud-firestoreloaddata

Reactjs fetch data from firestore when click button


I want to load data from firestore when user click handleReset(). When i click handleReset() it should load data from firestore and store in localstorage. I'm using reactjs. Error message Cannot read property 'map' of undefined.

admin.js

  handleReset(e) {
    const products = getDefaultProducts();
    saveProducts(products);
    this.setState({products});
    alert('Product Reset');
  }

product.js

export const getDefaultProducts = () => {

  const ref = firebase.firestore().collection('vouchers').doc('default');
  console.log('ref', ref)
    ref.get().then((doc) => {

      if (doc.exists) {
        return [
          { id: 'v5', qty: doc.data().v5 }, 
          { id: 'v10', qty: doc.data().v10, }, 
          { id: 'v20', qty: doc.data().v20 }, 
          { id: 'v50', qty: doc.data().v50 }, 
          { id: 'v100', qty: doc.data().v100 }
        ];  
      } else {
        console.log("No such document!");
      }
    });
}

export const saveProducts = (products) => {
  products = products.map(prd => {
    prd.qty = isNaN(+prd.qty) ? 0 : prd.qty
    return prd;
  });

  localStorage.setItem(STORAGE_KEY, JSON.stringify(products));
}


Solution

  • The answer is in your error message. products object is undefined because you are not returning anything from getDefaultProducts. The ref.get().then(... is a promise, so that inner function (where you return) is being executed later after your function has completed.

    To fix this, in getDefaultProducts you must return a Promise, and then use the appropriate .then method to access the results.

    const getDefaultProducts = () => {
        const ref = firebase.firestore().collection('vouchers').doc('default');
        console.log('ref', ref);
        // see we've added a return statement here, to return a Promise from this method
        return ref.get().then((doc) => {
            if (doc.exists) {
                return [
                    { id: 'v5', qty: doc.data().v5 },
                    { id: 'v10', qty: doc.data().v10, },
                    { id: 'v20', qty: doc.data().v20 },
                    { id: 'v50', qty: doc.data().v50 },
                    { id: 'v100', qty: doc.data().v100 }
                ];
            } else {
                throw new Error("No such document!"); // throw error here to cause current promise to be rejected
            }
        });
    }
    
    function handleReset(e) {
        getDefaultProducts().then((products) => {
            saveProducts(products);
            this.setState({ products });
            alert('Product Reset');
        }, (err) => {
            // this will be executed if firestore returns an error or document doesn't exist
            console.log(err);
        });
    }