Asset Name Becomes Null During Asset Load

Hi, I’m trying to load a bunch of assets and then just print the asset names once they have completed loading. However, with the following code all the assets start to load and many print out fine once loaded, but then it crashes with the following error.

TypeError: Cannot read properties of undefined (reading ‘name’)

Is it because I have a ready function for each object or something? It looks like some assets have finished loading while other are just starting to load. What would be the correct format to put this in to avoid the error?

Main.prototype.load_streaming_assets= function (tag) 
{
    var assets = this.app.assets.findByTag(tag);
    var count = 0;

    for (var i = 0; i < assets.length; i++) 
    {
        this.app.assets.load(assets[i]);
        console.log("Start loading asset "+assets[i].name)//prints for all assets
        assets[i].ready(function()
            {
                count++;
                console.log("%cAsset "+count+" Ready: "+assets[i].name,'color: #bada55'); //Prints fine for a bunch of assets but then errors.
            }
        );
    }

Its because you are in a closure and variable i is captured. It changes value (as it is going through a loop) so by the time the callback is called, i will reach value assets.length which is beyond the array buffer.

Instead, use the asset that is returned by the ready callback.

Main.prototype.load_streaming_assets = function (tag) {
    var assets = this.app.assets.findByTag(tag);
    var count = 0;

    for (var i = 0; i < assets.length; i++) {
        this.app.assets.load(assets[i]);
        console.log("Start loading asset " + assets[i].name)//prints for all assets
        assets[i].ready(function (asset) {
            count++;
            console.log("%cAsset " + count + " Ready: " + asset.name, 'color: #bada55'); //Prints fine for a bunch of assets but then errors.
        }
        );
    }
}

JS documentation on closures: Closures - JavaScript | MDN

Specifically: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#creating_closures_in_loops_a_common_mistake

1 Like

If you were making my game, we would have been finished a long time ago :slight_smile:

Thanks

2 Likes

Actually I have another problem with this - variable scope.

If I have a variable outside the function called something like:

this.streaming_assets_group_1_loaded=false

…it seems I cant change that within the assets[i].ready function as the ‘this’ becomes anonymous.

For example it seems that doing:

this.streaming_assets_group_1_loaded=true

WIthin the function just creates somekind of new variable? Any ideas how to access the variable from within the ready function?

A common practice is to use a local self variable:

const self = this;
assets[i].ready(function (asset) {
   self.streaming_assets_group_1_loaded = true;
}
2 Likes