Home > Enterprise >  How to set an array containing data from firestore query result in my code?
How to set an array containing data from firestore query result in my code?

Time:09-27

I successfully get the Orders with order_id and orders_data from firestore database and show in console, but I am unable to set the state of orders variable, I'm noob here. I tried the commented part but it doesn't work to setOrders. Please give any solution and do tell why my commented part isn't setting data.

Orders.js

import React, { useEffect, useState } from 'react';
import './Orders.css';
import { db } from './firebase';
import { useStateValue } from './StateProvider';
import { doc, query, getDocs, orderBy, collection, getDoc, onSnapshot } from "firebase/firestore";
import Order from './Order';

function Orders() {
  const [{ basket, user }, dispatch] = useStateValue();
  const [orders, setOrders] = useState([]); //Initial value will be empty array

  useEffect(() =>{
    if(user){
      async function fetchData() {
        // You can await here
        const ordersRef = collection(db,"users",user?.uid, "orders");
        const q = query(ordersRef, orderBy("created", "desc"));
        const querySnapshot = await getDocs(q);
        querySnapshot.forEach((doc) => {
          console.log(doc.id, " => ", doc.data());
        });
        
        //console.log("Got Orders>>",orders)
        //   setOrders(querySnapshot.forEach((doc =>({
        //     id: doc.id,
        //     data: doc.data()
        //   }))));
        //...
     }
      fetchData();
     }else{
       setOrders([]);
     }  
  }, []); //You have to have [] here. This makes it run only once. 

  return (
    <div className="orders">
        <h1>Your Orders</h1>
        <div className="orders__order">
          {orders?.map(order =>{
            <Order order={order}/>
          })}
        </div>
    </div>
  )
}

export default Orders

Order.js

import React from 'react';
import CheckoutProduct from './CheckoutProduct';
import './Order.css';
import moment from 'moment';

function Order({order}) {
  return (
    <div className="order">
        <h2>Order</h2>
        <p>{moment.unix(order.data.created).format("MMMM Do YYYY, h:mma")}</p>
        <p className="order__id">
            <small>{order.id}</small>
        </p>
        {order.data.basket?.map(item =>{
            <CheckoutProduct
            id = {item.id}
            title = {item.title}
            image = {item.image}
            price = {item.price}
            rating = {item.rating}
            />
        })}
    </div>
  )
}

export default Order

CodePudding user response:

I see. You should use map function instead of foreach

setOrders(querySnapshot.map((doc =>({
    id: doc.id,
    data: doc.data()
}))));

CodePudding user response:

data() is a queurySnapshot Object and it does not have a map fucntion to use, so we have to do it like this.

setOrders(querySnapshot.docs.map(doc =>({
    id: doc.id,
    data: doc.data()
})));

  • Related