Calling variables from AssetManager

Hi,
This has been killing me for days… I wanted to call a certain variable from AssetManager but keep getting -> “undefined” response.

//global variable
Var length;

var assetsManager = new BABYLON.AssetsManager(scene);
var meshTask = assetsManager.addMeshTask("object", "", "./objectDirectory/", "object.gltf");

meshTask.onSuccess = function (task) {

length = this.loadedMeshes.length;

console.log(length); // this works -> response 23

}

// calling outside the function
console.log(length); // this doesn’t work. -> response “undefined”

Am I missing something ?

Thanks.

Without a playground it is difficult to be definitive but would suggest that you are getting undefined outside the function because this line is being called before meshTask has successfully finished and so, as it says, length is not yet defined.

Everything you want to do to loaded meshes must be done inside the onSuccess function.

Apparently if I add a timeout it works.

     	setTimeout(function () {
	    console.log(length);			
		    }, 5000);

I suppose I was calling the function before the task has finished … But isn’t this the job of -< meshTask.onSuccess ??

No

the interpreter farms out the load task and goes straight to the next block of code, it does not hang around waiting for the task to finish before executing the next block of code. Once the load task has been completed the interpreter is notified and then the onSuccess code executed.

This way, for example, while the models are being loaded the interpreter can get on with building a menu system.

Ok I understand.
So is there a way to notify an external calling function that all the assets are now loaded and are ready to be called ? what approach would you advice ? Thanks.

You could either pass a callback in or use the scene on Ready observable to not be forced to pass it all the way down.

Thanks !
I will check the scene on Ready observable approach.

What about using AssetsManager.loadAsync() https://doc.babylonjs.com/api/classes/babylon.assetsmanager#loadasync
AFAIU It returns a Promise which gets resolved if all Assetes are loaded.

I couldn’t find any examples on how to use

Do you have a simple example ?

loadAsync is only available on the sceneLoader if you prefere to call into it manually: https://www.babylonjs-playground.com/#WGZLGJ#1033

I have already seen that but couldn’t find any examples being used with AssetManager.

ok :slight_smile: there are just no async capabilities with asset manager and the callback pattern will be your best friend there.

That’s because the “On Success” does not fire till its done so the length never gets bound and gets tossed into the stack basically. While your thread continues on to process the console log that was defined on the line below.

If you have an expected number of assets you are loading you could have a variable that increments on each OnSuccess and then fire a function to see if the incremented number matches what you are expecting if so then do some sort of response.

What is the problem with firing up the external function from within onSuccess? Is it a scoping issue?

1 Like

I am trying to understand the sync capabilities of asset manager with external calling functions.

Currently I have solved it by putting the external calling function after assetsManager.load();

Seems to work … :slight_smile: But I don’t know if it’s a best way to ensure that external calling functions don’t return -> ‘undefined’ values.

example: asset_length = this.loadedMeshes.length; (from asset manager)

function external () {
console.log(asset_length); // this doesn’t work. -> response “undefined”
}

The best way is to wait for onSuccessCallback before doing anything else.

Indeed @sebavan. I am also taking this route. Thanks !