0

This question looks like an other question from me: NodeJS Local variable in callback but I think it's different, because the solution from the answer isn't working here.

I have an async.eachOfSeries() function which will loop over some collections from a shop. Depending on a property it will create a category, or it will try to get an existing category. Depending on that result: a new category will be created or the existing category will be updated. After that the async callback is called to get further with the next collection. But when the code will call the callback, I get the error collectionsDone is not a function. Where that function is my callback. I have tried it with IIFE based on the answer from the mentioned question but that doesn't seems to work.

How can I solve this?

    async.eachOfSeries(shop.collections, function(collection, collectionsDone){
        if(!collection.countrId){
            //This collection doesn't seems to be synced to countr yet
            createCategory(collection[language].name, access_token, function(err, category){
                if(category){
                    collection.categoryId = category._id;
                }

                return collectionsDone();
            })
        }else{
            //It looks like that this category is already synced, but maybe we should update it
            var link = 'categories/' + collection.categoryId;
            (function(collectionsDone){
                externalService.callApi({url: link}, null, access_token, function(err, category){
                    console.log("err", err, "category", category);
                    if(err.error == "not_found"){
                        createCategory(collection[language].name, access_token, function(err, category){
                            if(category){
                                collection.categoryId= category._id;
                            }
                            return collectionsDone();
                        })
                    }else{
                        if(category.name != collection[language].name){
                            var data = {
                                _id: category._id,
                                name: collection[language].name,
                                color: category.color,
                                visible: category.visible
                            };
                            var url = 'categories/' + category._id;
                            externalService.callApi({
                                url: url,
                                method: "PATCH"
                            }, data, access_token, function(err, category){
                                return collectionsDone();
                            })
                        }else{
                            return collectionsDone();
                        }
                    }
                })
            })(collectionsDone);
        }
    }, function(){
        //collectionsDone()
        shop.save(function(err, result){
            console.log("shop save", err, result);

            if(err){
                return callback({code: 500, msg: err});
            }
            return callback(null, result);
        })
    })
NVO
  • 2,566
  • 5
  • 27
  • 57

2 Answers2

1

As mentioned in the async official documentation, the "collectionsDone" function here is purely internal inside the loop function, so it can't work with "return" in the callback.

In other words, "collectionsDone" is only a generic function to switch to the next iteration of the async loop. There is no need to pass it once the loop is terminated.

  • Do you know if there is a way to make this working via an other way? – NVO Jan 25 '18 at 12:56
  • If I understand well, you might rather need the "async.waterfall" function which allows you to run an array of functions in series, each passing their results to the next in the array. This is explained in the official documentation, and shortly illustrated here: https://coderwall.com/p/zpjrra/async-waterfall-in-nodejs –  Jan 26 '18 at 08:13
0

I was missing the key in the callback, so it must be

async.eachOfSeries(shop.collections, function(collection, key, collectionsDone){
NVO
  • 2,566
  • 5
  • 27
  • 57