单击按钮时,ReactJS从Firestore获取数据

时间:2019-07-22 08:56:43

标签: javascript reactjs firebase google-cloud-firestore loaddata

我想在用户单击handleReset()时从Firestore加载数据。当我单击handleReset()时,它应该从Firestore加载数据并存储在localstorage中。我正在使用reactjs。错误消息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));
}

1 个答案:

答案 0 :(得分:1)

答案在您的错误消息中。 products对象未定义,因为您没有从getDefaultProducts返回任何内容。 ref.get().then(...是一个承诺,因此内部函数(您返回的位置)将在函数完成后再执行。

要解决此问题,必须在getDefaultProducts中返回一个Promise,然后使用适当的.then方法来访问结果。

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);
    });
}