Reading JSON crashes on HTML5 target (Assets.getText)

Hi,

I co-developed a HaxeFlixel game. It uses this library I created, which includes a class that loads JSON from assets and parses the values.

I developed and tested this locally using neko, and everything works fine. When I target html5, I get this cryptic-looking error in the JS console:

Uncaught TypeError: Cannot read property 'h' of undefined
    at DefaultAssetLibrary.getText (Backeroids.js:3317)
    at Function.lime_Assets.getText (Backeroids.js:6590)
    at Function.openfl_Assets.getText (Backeroids.js:6036)
    at Function.helix_data_Config.loadAndCacheJson (Backeroids.js:5759)
    at Function.helix_data_Config.get (Backeroids.js:5708)
    at Backeroids.js:95643
    at Backeroids.js:98664
getText @ Backeroids.js:3317
lime_Assets.getText @ Backeroids.js:6590
openfl_Assets.getText @ Backeroids.js:6036
helix_data_Config.loadAndCacheJson @ Backeroids.js:5759
helix_data_Config.get @ Backeroids.js:5708
(anonymous) @ Backeroids.js:95643
(anonymous) @ Backeroids.js:98664
Backeroids.js:72197 Uncaught TypeError: Cannot read property 'windows' of null
    at Object.lime_system_System.embed.$hx_exports.lime.embed (Backeroids.js:72197)
    at (index):57
lime_system_System.embed.$hx_exports.lime.embed @ Backeroids.js:72197
(anonymous) @ (index):57

The line it’s referring to in Helix code is basically this:

var text = openfl.Assets.getText("assets/data/config.json");

I’ve verified that assets/data/config.json exists on disk in export/html5/bin, and that I can read it by hand – if I add trace(openfl.Assets.getText(...)) as the first line in Main.hx before super, it prints the contents correctly.

For example, here are the previous ten lines in JS right before the line that crashes:

backeroids_SoundManager.playerShoot = new flixel_system_FlxSound();
backeroids_SoundManager.playerExplode = new flixel_system_FlxSound();
backeroids_SoundManager.asteroidHit = new flixel_system_FlxSound();
backeroids_SoundManager.asteroidSplit = new flixel_system_FlxSound();
backeroids_SoundManager.buttonClick = new flixel_system_FlxSound();
backeroids_SoundManager.enemyShoot = new flixel_system_FlxSound();
backeroids_SoundManager.enemyHit = new flixel_system_FlxSound();
backeroids_SoundManager.enemyExplode = new flixel_system_FlxSound();
backeroids_SoundManager.shooterAmbient = new flixel_system_FlxSound();
backeroids_SoundManager.mineExplode = new flixel_system_FlxSound();
backeroids_states_LevelSelectState.PADDING = 32;
openfl_Assets.cache = new openfl_AssetCache();
openfl_Assets.dispatcher = new openfl_events_EventDispatcher();
lime_Assets.cache = new lime_AssetCache();
lime_Assets.libraries = new haxe_ds_StringMap();
lime_Assets.onChange = new lime_app_Event_$Void_$Void();
lime_Assets.initialized = false;
backeroids_states_PlayState.NUM_INITIAL_ASTEROIDS = helix_data_Config.get("asteroids").initialNumber;

I tried switching to a static method where my game reads the contents and passes it in instead of the library reading it, but that results in the same error. I think it comes down to how Haxe compiles the code – in many of my game state classes, I have static inline variables (constants) that read from this config, and it’s trying to populate those values.

I also tried switching to Assets.getBytes, but I can’t see any way to convert a byte array into a string.

I’m really at a loss as to how to fix this.

For reference, I’m using HaxeFlixel 4.3.0, Lime 2.9.1, and OpenFL 3.6.1.

Maybe it’s just because your JSON is invalid. Try to remove the comments in the JSON.

hi tested the json it is loading perfectly i think the problem is in the parsing , i use this lib TJSON to parse the data.

Snippet :

var DATA:Array<DataModal>;
var loadedData:String = Assets.getText("data/data.json");
DATA = TJSON.parse(loadedData);

typedef DataModal=
{
	var ID:Int;
	var NAME:String;
    var TAGS:Array<String>;
}

also then you can access DATA anywhere if you make it static .

Or as a fast workaround, if the library uses haxe.Json

https://api.haxe.org/haxe/Json.html

Cross-platform JSON API: it will automatically use the optimized native API if available. Use -D haxeJSON to force usage of the Haxe implementation even if a native API is found: This will provide extra encoding features such as enums (replaced by their index) and StringMaps.

See if it helps?

openfl test html5 -DhaxeJSON

I also tried removing the comments, it didn’t make any difference. (It shouldn’t; the stack shows that OpenFL is trying to read the file, not actually understand/parse it as JSON.)

I solved this by removing the use of Config.get(...) in private static inline class-level variables (constants), and moved these into create. Everything works as expected.

I think OpenFL just didn’t reach that point where everything is initialized enough to read the file. I can live with this solution.

Sorry for all the noise!

2 Likes