Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

I have an array of different IDs and I want to fetch data from each IDs . Is it possible?

I have an array of mongoDB ids.

const pId =  ['62b3968ad7cc2315f39450f3', '62b37f9b99b66e7287de2d44']

I used forEach to seperate the IDs like :

pId.forEach((item)=>{
console.log(item)
})

but I have a database(products) from where I want to fetch data from. So I tried

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

   const [product, setProduct] = useState([{}]);
useEffect(() => {
            pId?.forEach((item) => {
                const getProduct = async () => {
                    try {
                        const res = await userRequest.get("/products/find/" + item)
                        setProduct(res.data)
                    } catch (err) {
                        console.log(err)
                    }
                }
                getProduct()
            })
        }, [pId])

I used useState[{}] because I want to collect the data in an array of objects.

>Solution :

I used useState[{}] because I want to collect the data in an array of objects.

Your code isn’t collecting objects into an array. It’s setting each result of the query as the single state item (overwriting previous ones).

If you want to get all of them as an array, build an array; one way to do that is map with the map callback providing a promise of each element, then use Promise.all to wait for all of those promises to settle:

// The usual advice is to use plurals for arrays, not singulars ("products", not "product")
const [products, setProducts] = useState([]); // Start with an empty array
useEffect(() => {
    if (pId) {
        Promise.all(pId.map((item) => userRequest.get("/products/find/" + item)))
            .then((products) => setProducts(products))
            .catch((error) => console.log(error));
    }
}, [pId]);

Note that if pId changes while one or more userRequest.get calls are still outstanding, you’ll get into a race condition. If userRequest.get provides a way to cancel in-flight calls (like fetch does), you’ll want to use that to cancel the in-flight calls using a cleanup callback in the useEffect. For example, if userRequest.get accepted an AbortSignal instance (like the built-in fetch does), it would look like this:

const [products, setProducts] = useState([]);
useEffect(() => {
    const controller = new AbortController();
    const { signal } = controller;
    if (pId) {
        Promise.all(pId.map((item) => userRequest.get("/products/find/" + item, { signal })))
            .then((products) => setProducts(products))
            .catch((error) => {
                if (!signal.aborted) {
                    console.log(error);
                }
            });
    }
    return () => {
        controller.abort();
    };
}, [pId]);

Again, that’s conceptual; userRequest.get may not accept an AbortSignal, or may accept it differently; the goal there is to show how to cancel a previous request using a useEffect cleanup callback.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading