Home > Net >  JS: several async functions return "this value was evaluated upon first expanding"
JS: several async functions return "this value was evaluated upon first expanding"

Time:10-14

I am using powerbi rest api to get states of slicers from the active page. To get only slicers which states are not empty I have written a simple function. However, in the console.log statement I see "this value was evaluated upon first expanding" and hence my var is empty.

//TODO: not working
async function getSlicersStates(reportObj) {
    // let states = []; //Also empty
    const page = await reportObj.getActivePage(); //Get page
    const visuals = await page.getVisuals();  //Get visuals

    visuals.forEach(async function(vis){ 
        let states = [];
        if (vis.type == "slicer") { //filter all but slicers
            let state = await vis.getSlicerState(); //get state of each slicer
            if (state.filters.length > 0) {
                // Push state and title
                states.push({ title: vis.title, data: state});
            }
        }
        return states; //Empty == this value was evaluated upon first expanding
    });
}

I have tried to put "return states;" on different places in the function but it has not helped.

How I call the function

getSlicersStates(reportObj)
.then(function(states) {
    console.error(states); //this value was evaluated upon first expanding
})
.catch(function(err) {
    console.error(err);
})

CodePudding user response:

The message you're seeing is not related to your problem. That's a standard information message that some implementations of the console show when logging objects, to help point out that changes to the object may be included in the log.

Instead, the main issue is that you don't have a return statement in getSlicersStates. There's one inside the .forEach, but that has no effect. .forEach doesn't pay any attention to the return value. You also seem to be expecting .forEach to wait for asynchronous things to finish, but it will not do so.

If you want to have an asynchronous loop that waits, you cannot use .forEach. Here's an alternative:

async function getSlicersStates(reportObj) {
    const page = await reportObj.getActivePage(); //Get page
    const visuals = await page.getVisuals();  //Get visuals

    let states = [];
    for (const vis of visuals) {
        if (vis.type == "slicer") { //filter all but slicers
            let state = await vis.getSlicerState(); //get state of each slicer
            if (state.filters.length > 0) {
                // Push state and title
                states.push({ title: vis.title, data: state});
            }
        }
    }
    return states;
}
  • Related