Search code examples
javascriptnode.jspromiseecmascript-5

Getting null in values from Promise.all


I am using promises. This is in continuation to my question here

The issue I am having is that in response, i.e. an array of objects is having null values. I will try to explain this

  1. First I get the userId
  2. Get user whishlist products from the userId
  3. Then using userId I get stores/shop list
  4. Then I iterate over store list and call another API to check if this store is user favourite store.
  5. Then I get the products of each store and append in an object and return.

    function getStoresList(context) {
        const userID = common.getUserID(context)
        let userWishListProd = []
    
        return userID
            .then(uid => Wishlist.getUserWishlistProducts(uid).then((products) => {
                userWishListProd = products.data.map(product => +product.id)
                return uid
            }))
            .then(uid => api.getOfficialStoresList(uid).then((response) => {
                    if (!response.data) {
                        const raw = JSON.stringify(response)
                        return []
                    }
    
                    const shops = response.data
                    return Promise.all(
                            shops.map((shop) => {
                                const id = shop.shop_id
                                const shopobj = {
                                    id,
                                    name: shop.shop_name,
                                }
                                return favAPI.checkFavourite(uid, id)
                                    .then((favData) => {
                                        shopobj.is_fave_shop = favData
    
                                        // Fetch the products of shop
                                        return getProductList(id, uid)
                                            .then((responsedata) => {
                                                shopobj.products = responsedata.data.products.map(product => ({
                                                    id: product.id,
                                                    name: product.name,
                                                    is_wishlist: userWishListProd.indexOf(product.id) > -1,
                                                }))
                                                return shopobj
                                            })
                                            .catch(() => {})
                                    })
                                    .catch(err => console.error(err))
                            }))
                        .then(responses => responses)
                        .catch(err => console.log(err))
                })
                .catch(() => {}))
            .catch()
    }
    

The response I get is

[{
        "id": 1001,
        "name": "Gaurdian Store",
        "is_fave_shop": "0",
        "products": [{
            "id": 14285912,
            "name": "Sofra Cream",
            "is_wishlist": false
        }]
    },
    null,
    null,
    {
        "id": 1002,
        "name": "decolite",
        "is_fave_shop": "1",
        "products": [{
            "id": 14285912,
            "name": "Denca SPF",
            "is_wishlist": false
        }]
    }
]

The actual store are coming as 4 but instead of it null gets appended. What is wrong I am doing with Promises here.


Solution

  • This appears to have to do with your .catch(() => {}) and .catch(err => console.error(err)) invocations. If one promise in your loop has an error, it will be transformed to an undefined value (optionally being reported before), so that Promise.all will fulfill with an array that might contain undefined values. If you JSON.stringify that, you'll get null at those indices.

    Drop the .catch(() => {}) statements that do nothing (or replace them with logging ones), and check your error logs.