Home > Blockchain >  Filtering data after fetching in React
Filtering data after fetching in React

Time:02-14

I need to make a list of objects based on combined data from 2 arrays, one comes from a localStorage and the second one from Django backend. First of all objects from localStorage are displayed by showCart() function

export const showCart = () => {
    if (typeof window !== undefined) {
        if (localStorage.getItem("cart")) {
            return JSON.parse(localStorage.getItem("cart"));
        };
    };
};

it returns data in this format: FE: { id: 1, amount: 7, size: "L", product: 1 }. product is the Foreign Key needed to match data from other array.

The second array comes form a backend and it is feched by getAllProducts() function

export const getAllProducts = () => {
    return fetch(`${url}/products/`, {method: "GET"})
    .then((response) => {
        return response.json();
    })
    .catch((error) => console.log(error))
};

It returns data in this format: FE { name: "Red", id: 3, price: 33, image:"some-url"} ​​

Now I need to create another list of objects by merging then by product of an object in first array with id of an object from the second one. The objects in the third array need to contain amount and size from first array as well as name, price and image from the second one. In the end I want to store it in useState().

This is what I came up with, I guess my code stops working arter first for loop:

const [cart, setCart] = useState([]);

   const CheckAnonymousCart = () => {
        getAllProducts()
        .then((data) => {
            const localCart = showCart();
            var products = [];
            for (let i = 0; i < localCart.lenght; i  ) {
                for (let y = 0; y < data.lenght; y  ) {
                    if (localCart[i].product === data[y].id) {
                        console.log(localCart[i].product, data[y].id)
                        const item = {
                            name: data[y].name,
                            price: data[y].price,
                            image: data[y].image,
                            amount: localCart[i].amount,
                            size: localCart[i].size,
                        }
                        products.push(item)
                        break;
                    }
                }
            }
            setCart(products);
        })
        .catch((error) => console.log(error))
    };

​​Any thoughts?

CodePudding user response:

In addition to Jacob's comment, you probably want to avoid FETCH'ing all products from the DB, because it requires more DB resources, most of the info is not required, and it makes the for-loop take longer to JOIN both lists.

Ideally, you would use a parameterized query like so:

return fetch(`${url}/products/?id=1&id=2&id=3`, {method: "GET"})

Where ?id=1&id=2&id=3 are a subset of the product IDs that you're retrieving.

Note: You will also want to sanitize/validate the product IDs in localStorage, because the data can be modified by the end-user, which is a potential attack vector by malicious users.

CodePudding user response:

The problem could simply be the typo from the for loop conditions, but you can also accomplish this more succinctly using the JS ES6 methods:

const products = localCart.map(item => {
    const match = data.find(x => x.id === item.product);
    return {
        amount,
        size,
        name: match?.name,
        price: match?.price,
        image: match?.image
    }
});
  • Related