0

Here is my problem:

My main function:

const mainFunction = () => {
    const reports = JSON.parse($sessionStorage.datas);
    // reports contains array of objects.
    // consider i have two objects inside one array, so the loop will execute two times now
    reports.forEach((item) => {
        this.openReport(item);
    });
};
mainFunction();

openReport function:

this.openReport = (report)  => {
    console.log('openReport working');
    // some async functions will be here
    // ajax calls
    this.openTab(report);
};

openTab function:

this.openTab = (report) => {
    console.log('handleOpenTab function working');
}

Output:

// Now i have two objects, so forEach works two times.
'openReport working'
'openReport working'

'handleOpenTab function working'
'handleOpenTab function working'

My expected output :

'openReport working'
'handleOpenTab function working'

'openReport working'
'handleOpenTab function working'

How to achieve this? i am unable to use async await inside my forEach function, because using old node version.

If its possible to use async/await for this problem, i will try to upgrade my node version.

Mohamed Sameer
  • 2,998
  • 3
  • 22
  • 51
  • 2
    You need to use Promises. Your older node version still supports Promises, right? – TKoL Feb 06 '19 at 11:12
  • Use timestamp for each ajax call and include the same as option param. Cross-check with the timestamp once you get the response – Aravind Cheekkallur Feb 06 '19 at 11:12
  • @TKoL which function needs to be convert as a promise? – Mohamed Sameer Feb 06 '19 at 11:18
  • How to use async/await for this problem? if i find a solution, i will upgrade node version. – Mohamed Sameer Feb 06 '19 at 11:18
  • @MohamedSameer your OpenReport function says it does ajax calls and stuff, so that function should return a promise that resolves AFTER the ajax calls are done and after `this.openTab` is called. Then you have to adjust mainFunction to use promises, I would personally use a recursive loop – TKoL Feb 06 '19 at 11:51
  • [Don't use `forEach`](https://stackoverflow.com/q/37576685/1048572) – Bergi Feb 06 '19 at 11:58

1 Answers1

0

Using promises, it would look something like this probably:

this.openReport = (report) => {
    console.log('openReport working');
    // some async functions will be here
    // ajax calls
    return new Promise(function(resolve, reject) {
        ajaxCall('url', resolve); // reject as necessary!
    }).then(answer => {
        this.openTab(report);
        return answer;
    });
};

const mainFunction = () => {
    const reports = JSON.parse($sessionStorage.datas);
    // reports contains array of objects.

    function getNextReport(index) {
        if (index >= reports.length) return Promise.resolve();
        let item = reports[index];
        return this.openReport(item).then(function(answer) {
            // do something with answer
            return getNextReport(index+1);
        });
    }

    return getNextReport(0);
};
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
TKoL
  • 13,158
  • 3
  • 39
  • 73
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Feb 06 '19 at 11:57
  • This isn't helpful without an alternative. I assume you're talking about my mainFunction, so I would appreciate seeing how to achieve the same ability to loop-and-wait without the antipattern. – TKoL Feb 06 '19 at 12:44
  • 1
    I've edited to a version that just uses promise chaining instead – Bergi Feb 06 '19 at 13:37
  • I thought it might look something like that, wasn't sure. – TKoL Feb 06 '19 at 14:37