0

I am kinda new at react and trying to make two axios get call according to results of first call as you can see in my code. Eventually I am trying to .map the response data in swiper component. However my code is not working properly. The problem is, the data from the first call is displayed on the component properly while the images from the second call are not.

        const [picks, setPicks] = useState([]);
        const getAllPicks = async () => {
        try {
            axios.get(".../shoppicks").then(async (response) => {
                const responseData = await response.data.result;
                for (let i = 0; i < responseData.length; i += 1) {
                    axios.post(".../getimage", { shopID: response.data.result[i]._id }).then((res) => {
                        if (res.data.header.arg === "No image found") {
                            // dummy photo for corrupted responses
                            responseData[i].imgPath = "#"
                        } else {
                            responseData[i].imgPath = res.data
                        }
                    })
                }
                return responseData
            }).then((responseData) => {
                setPicks(responseData)               
                console.log(responseData) row 38 logs the data properly
                console.log(picks) row 39 logs empty array
            })
                .catch((error) => console.log(JSON.stringify(error)));
        }
        catch (error) {
            console.log(error)

        };
    }
    useEffect(() => {
        getAllPicks();
    }, []);

Here where I try .map the data

                {picks?.map((pick: IHomePickType) => (
                    <><SwiperSlide  key={pick._id}>
                        <CardMedia image={pick.imgPath} component="img" />
                        <div>
                            <h2>{pick._id}</h2>
                        </div>
                    </SwiperSlide></>
                ))}

Additionally it throws "Each child in a list should have a unique "key" prop." console error even though the picks data has unique keys

ardabzlk
  • 91
  • 8
  • *"row 39 logs empty array"* - Is that the specific indication of a problem you're referring to? Because that is expected and correct behavior. – David Oct 18 '22 at 14:43
  • 1
    You ahve a mixture of `promise.then` and `async/await`. Exmaple: `axios.get(".../shoppicks").then(async (response)` pick one of those and use it. HAve in mind you do not await the `axios.post(".../getimage"` and return the collection. Advice pick async/await and use it for whole the code, remove the promise.then.then.catch – Svetoslav Petkov Oct 18 '22 at 14:55
  • @David it is an indication of the problem. I expected to see the data that I set at the setPicks function. Why it is correct behavior? – ardabzlk Oct 18 '22 at 15:01
  • Does this answer your question? [The useState set method is not reflecting a change immediately](https://stackoverflow.com/questions/54069253/the-usestate-set-method-is-not-reflecting-a-change-immediately) – David Oct 18 '22 at 15:03
  • @SvetoslavPetkov I've refactored the code accordingly and solved my problem thanks a lot. However do you have any idea why I get "Each child in a list should have a unique "key" prop." error? I both tried to assign uid with v4() function of "uuid" library. – ardabzlk Oct 18 '22 at 15:38
  • 1
    If you still have the surrounding `<>` in `<>>` - reomve them since they do nothing. And make sure tow things: `1: pick_id is unique` and `2: you dont't have another component that renders using .map( on the page, and that other .mpa does not set unique key prop ` – Svetoslav Petkov Oct 18 '22 at 15:42
  • @SvetoslavPetkov removing <> tags worked! Thanks a lot both of you. – ardabzlk Oct 18 '22 at 15:45

1 Answers1

0

I've updated my code according the comments. It is working now. here is the final code

    const [picks, setPicks] = useState([]);
const getAllPicks = async () => {
    try {
        const response = await axios.get("../shoppicks");
        const data = await response.data.result;
        for (let i = 0; i < data.length; i += 1) {              
            const imgResponse = await axios.post("../getimage", { shopID: data[i]._id });
            if (imgResponse.data.header.arg === "No image found") {
                // dummy photo for corrupted responses
                data[i].imgPath = "#"
            } else {
                data[i].imgPath = imgResponse.data.result.imgPath
            }
        }
        setPicks(data)
    }
    catch (error) {
        console.log(error)

    };
}

component =>

            {picks?.map((pick: IHomePickType) => (
                <SwiperSlide key={pick._id}>
                    <CardMedia image={pick.imgPath} component="img" />
                    <div>
                        <h2>{pick._id}</h2>
                    </div>
                </SwiperSlide>
            ))}

Thanks

ardabzlk
  • 91
  • 8