1
 const [cart, setCart] = useState({})

    useEffect(()=>{
        const items = JSON.parse(localStorage.getItem('cart')); // return [5,6]
        let array = [];
        if(items && items.length){
            items.map(function (cart_id){
                getPack(cart_id).then((result)=>{
                    array.push(result.data) // not working
                    console.log(result.data) // got data as object!
                })
            })
            setCart(array);
            console.log(array); // return empty
        }
    }, []);

    const getPack = async(id) => {
        return await Api.Get('getPack', false, false, id); // get data from api
    }

What I trying to do is after get data from api from async function called getPack set it to object. I got data from getPack but I want to set it to array, I used array.push but it's not working. Any idea what is wrong?

4 Answers 4

1

You return promise which is async, so your code console.log(array); will be executed before you get the response from your endpoint and entering inside callback in then. In other words, there is no guarantee that your code after getPack(cart_id).then will be execute when array is fields because it is asynchronous.

As an option create an additional state for your array instead of declaring it inside the useEffect:

const [array, setArray] = useState([])
useEffect(()=>{
    const items = JSON.parse(localStorage.getItem('cart')); // return [5,6]
    if(items && items.length){
        items.map(function (cart_id){
           getPack(cart_id).then((result)=>{
                setArray(oldArray => [...oldArray, result.data]) 
                console.log(result.data)
            })
        })
        console.log(array); // return empty
    }
}, []);

const getPack = async(id) => {
   return await Api.Get('getPack', false, false, id); // get data from api
}
Sign up to request clarification or add additional context in comments.

4 Comments

Error: TypeError: Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method. on this line=> setArray([...array, ...result.data])
@tourtravel if result.data is object, I updated, I thought this is an array.
It working fine but there is one problem, array contains one object, while result.data has many objects, seems it replacing not add every object to array.
@tourtravel try setArray(oldArray => [...oldArray, result.data] );
1

You could use Promise.all() and create array, there is no need to use oldArray !

const [cart, setCart] = useState({})

    useEffect(()=>{
        const items = JSON.parse(localStorage.getItem('cart'));
        if(items && items.length){
            let promises = items.map(function(cart_id){
                return getPack(cart_id).then(function(result){
                    return result
                })
            })
            Promise.all(promises).then(function(results) {
                setCart(results)
            })
        }
    }, []);

    const getPack = async(id) => {
        return await Api.Get('getPack', false, false, id);
    }

Comments

0

You need to look into the response of "Api.Get" method.

const [cart, setCart] = useState([]) //changed {} to []

useEffect(()=>{
    const items = JSON.parse(localStorage.getItem('cart')); // return [5,6]
    let array = [];
    if(items && items.length){
        items.map(function (cart_id){
            getPack(cart_id).then((result)=>{
                array.push(result) // its working perfect my side
                console.log(result) // got data as object!
            })
        })
        setCart(array);
        console.log(array); // return array of objects
    }
}, []);

const getPack = async(id) => {
    return {data:1} 
    //await Api.Get('getPack', false, false, id); // get data from api
}

Comments

0

This part is not correctly written:

let array = [];
if(items && items.length){
    items.map(function (cart_id){
        getPack(cart_id).then((result)=>{
            array.push(result) // its working perfect my side
            console.log(result) // got data as object!
        })
    })
    setCart(array);
    console.log(array); // return array of objects
}

I haven't got a chance to test this particular piece of code but you'd better try something like:

if(items && items.length){
    let array = items.map(function (cart_id){
        return getPack(cart_id).then((result)=>{
            return result.data;
        })
    })
    setCart(array);
}

This way you loop items and assign to each new 'array' element the result of each promise resolved from the async method 'getPack(cart_id)'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.