Search code examples
javascriptes6-promiseautodesk-forge

missing timing from promised value


So I am using Forge with View API to analyze all parts from a model which contain concrete and hide everything that is not concrete. The problem is that the properties for checking concrete are called from a DB which requires me to make it a promise. Checking for concrete is working as expected and then the problem starts. I return the Ids containing concrete, but my function which is supposed to hide it uses the Ids before the promise is resolved, so the array is empty. console.log logs it as expected but everything else misses the timing. My code:

getProperties(dbId) {
    return new Promise((resolve, reject) => {
        this.gui.getProperties(
            dbId,
            args => {
                resolve(args.properties)
            },
            reject
        )
    })

}

async getConcreteIds() {
    let wallfloorids = this.getWallIds().concat(this.getFloorIds());
    let concreteIds = [];
    for (let id of wallfloorids) {
        let p1 = this.view.getProperties(id);
        p1.then(props => {
            for (let prop of props) {
                if (prop.displayCategory === "Materialien und Oberflächen" && prop.displayValue.contains("Concrete")) {
                    concreteIds.push(id);
                }
            }
        }).catch(() => {
        });
    }
    return new Promise((resolve, reject) => {
        try {
            resolve(concreteIds)
        } catch (e) {
            console.log("Err", reject)
        }
    })
}


async onlyConcrete() {
    this.getConcreteIds().then(concrete => {
        debugger;
        this.viewer.isolateById(concrete)
    });
}

Solution

  • Map an array of promises for your loop and use Promise.all() to resolve after all the promises in loop resolve

    Something like:

    async getConcreteIds() {
      let wallfloorids = this.getWallIds().concat(this.getFloorIds());
    
      let concreteIds = [];
    
      let promises = wallfloorids.map(id => {
        let p1 = this.view.getProperties(id);
        return p1.then(props => {
          for (let prop of props) {
            if (prop.displayCategory === "Materialien und Oberflächen" && prop.displayValue.contains("Concrete")) {
              concreteIds.push(id);
            }
          }
        });
      });
    
      return Promise.all(promises)
        .then(_ => concreteIds)
        .catch(err => console.log("Err", err))
    }