Proper use of async loaded mesh in scene class

Minimal example: https://playground.babylonjs.com/#D8NGJN#1

I am attempting the Playground to Production guided learning story: Playground to Production - Fruit Fallin' | Babylon.js Documentation

My production app is using the npm package template:

I would like to manipulate a mesh loaded with assetManager in the playground class. I can manipulate it in the async AssetsManager function when loaded, and i can see it when i perform console.log(scene.meshes). Yet console.log(scene.meshes[0]) returns undefined.

What is the proper way to access this mesh in the scene class after it is loaded? I know that console.log(thing) can be unreliable when dealing with async/await behavior, but not sure how to marry this behavior properly within classes.

The end goal is to take my game from playground to production with proper type annotations, etc. Basically I just want to continue following the official examples. Any help is appreciated, thanks.

Hi @genuflect,

You need to return a promise in your async loadDummy function. The skeleton of your function should look like this:

async function loadDummy(inputScene: BABYLON.Scene): Promise<BABYLON.AbstractMesh> {
    return new Promise((resolve, reject) => {
      
    });
}

Then you call your async call and the callback implementation of your async call (onSuccess) inside the function you pass to Promise constructor.

async function loadDummy(inputScene: BABYLON.Scene): Promise<BABYLON.AbstractMesh> {
    return new Promise((resolve, reject) => {
         // Your async call and your callback implementation.......
         // .....
         meshTask1.onSuccess = function (task) {
             // ....
         }
    });
}

Finally, in your callback implementation of onSuccess, you call resolve() on the target object you would like to return from your async function. E.g. Return the dummy mesh:

async function loadDummy(inputScene: BABYLON.Scene): Promise<BABYLON.AbstractMesh> {
    return new Promise((resolve, reject) => {
         // Your async call and your callback implementation.......
         // .....
         meshTask1.onSuccess = function (task) {
             // ....
             resolve(dummy);
         }
    });
}
4 Likes

@slin thanks for this, it unblocked me. I have a follow-on question for you if you don’t mind answering some Typescript knowledge:

My IntelliSense is yelling at me because Argument of type 'AbstractMesh | undefined' is not assignable to parameter of type 'AbstractMesh | PromiseLike<AbstractMesh>'. Type 'undefined' is not assignable to type 'AbstractMesh | PromiseLike<AbstractMesh>'.ts(2345)

This doesn’t show up in the playground but does in my ide (vscode). The supposedly offending line is line 20 in the playground: resolve(dummy).

Asserting const dummy: BABYLON.AbstractMesh | undefined = task.loadedMeshes.find((model) => model.name === "mixamorig:Skin"); doesn’t cause the error to go away.

To be clear, this compiles fine and I can view the result in my browser. Any idea how to resolve the error?

Thanks for answering, I clearly didn’t understand the promise syntax and how it interacts with Typescript/classes.

Probably here are some tips which may help - Argument of type 'import("babylonjs/Meshes/abstractMesh").AbstractMesh' Error

Hi @genuflect,

Since you have dummy: BABYLON.AbstractMesh | undefined, I guess it expects your return type to be PromiseLike<BABYLON.AbstractMesh | undefined>.

The other option you might consider: If dummy is undefined, there is possibly some error loading your mesh? You can use the reject() similarly to resolve().

async function loadDummy(inputScene: BABYLON.Scene): Promise<BABYLON.AbstractMesh> {
    return new Promise((resolve, reject) => {
         // whatever we had before for async call and onSuccess callback...
         // Error handlig
         meshTask1.onError = function () {
             // ....
             reject(new Error('some error msg'));
         }
    });
}

And then you can do:

try {
    loadDummy(scene);
} catch(error) {
    // handling error when mesh is undefined
}
2 Likes