0

I started to learn JS and got stuck on something super simple. I searched on internet and SE but couldn't find an answer.

I have simple button:

<button onClick="filtersearchWrapper()">look for filter</button>

which runs:

function filtersearchWrapper()
{
    filtersearch();
}

and filtersearch() is:

function filtersearch() {
    found = 0;
    for (i = 0; i < worksheetArray.length; i++) {
        filters = worksheetArray[i].getFiltersAsync().then(
            function(filtersArrayReturnedInPromise) {
                for (filter of filtersArrayReturnedInPromise) {
                    if (found == 1) {
                        break;
                    }
                    else
                    {
                        if (filter.getFilterType() == "quantitative" && filter.getFieldName().includes("[AutoFilter]")) {
                            console.log("aa" + filter.getFieldName());
                            found = 1;
                            filtername = filter.getFieldName();
                        }
                    }
                }
            })
    }

    return filtername;
}

The function performs async call (getFiltersAsync) and returns a promise which resolves to an array. I then cycle through this array and look for a particular entry I would like to return and use in the next function.

This console log in the deepest level works ok, but whole filtersearch() function does not return anything to the wrapper function.

I believe it's caused by value not being returned up in the for loops till end of function, but I don't know how to pass them through. How do I handle this?

Update

For you guys, who wandered here, here's how I solved the problem using article in the description. It turned out that when you start using async function then most likely you will have to remember about it till end of script.

in filterseach() there's only one small change added return before loop:

function filtersearch()
{

viz = getCurrentViz();
sheet=viz.getWorkbook().getActiveSheet();
worksheetArray = sheet.getWorksheets();
worksheets = sheet.getWorksheets();

found=0;

for (i=0;i<worksheetArray.length;i++){

    return  filters=worksheetArray[i].getFiltersAsync().then(
            function(filtersArrayReturnedInPromise){
                for ( var filter = 0, len = filtersArrayReturnedInPromise.length; filter < len; ++filter ) 
                    {
                    if (found ==1) {
                       break;
                    }else{

                    if (filtersArrayReturnedInPromise[filter].getFilterType()=="quantitative" && filtersArrayReturnedInPromise[filter].getFieldName().search("AutoFilter")>0)
                        {
                        found = 1;
                        filtername = filtersArrayReturnedInPromise[filter].getFieldName();
                        return filtername;
                        }

                    }
                    }
            });

    }   

}

but major change was done in the filtersearchWrapper() (which in fact was dropped and integrated in the main function later):

function filtersearchWrapper(){

  filtersearch().then(function(filter_found){

   //do some code here after filters are discovered

   });
}
darth0s
  • 165
  • 2
  • 13
  • There are a few problems there (unsurprising, if you're new!), but the main one is what's described in the linked question and addressed by its answers. If `filtersearch` is relying on an asynchronous API (which it is), then it, too, is asynchronous, as is anything calling it. You can't *return* the result, you can only either use a simple callback, or a promise, which is a structured, composible system for handling callbacks. – T.J. Crowder Apr 21 '17 at 14:13
  • One of the other issues in the code is that it's falling prey to [The Horror of Implicit Globals](http://blog.niftysnippets.org/2008/03/horror-of-implicit-globals.html) *(that's a post on my anemic little blog)*. You need to declare your variables, either with `var` or (if you're targeting only fairly cutting-edge browsers, or *transpiling* with something like [Babel](http://babeljs.io)), `let` or `const`. – T.J. Crowder Apr 21 '17 at 14:14
  • 1
    Whoa! @T.J.Crowder thanks for that edit - it was extensive one :D After I posted the question I got info that there's an answer here http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call and I am following Promise section there – darth0s Apr 21 '17 at 14:25
  • the problem I've been struggling with however is for loop runs only once. This is probably due to asynchronous execution inside synchronous for loop.. still can't find the solution for that :( – darth0s May 17 '17 at 13:39

0 Answers0