Return value from another JS?

I’m probably being a bit daft here but how do I return a value from another js, which is in your Hype resources? In the example below, I’m calling a js which loads a .json file and I’d like that to be returned to the main js.

main.js (on Scene Load)

function main(hypeDocument, element, event) {
	
	// Call loadJSON with json file target
	var jsonUrl = 'data/questions.json';
	var test = hypeDocument.functions().loadJSON(hypeDocument, [element,jsonUrl], event);
	
	console.log(test);
}

loadJSON.js

function loadJSON(hypeDocument, element, event) {

	// Define variables and receive jsonUrl from called script (i.e. main.js)
	var element_ = element[0];
	var jsonUrl = element[1];
	
	var jsonData;
	
    var request = new XMLHttpRequest();
    request.open('GET', jsonUrl, true);
    

    request.onload = function() {
        if (request.status >= 200 && request.status < 400) {

            jsonData = JSON.parse(request.responseText);
        } else {

        }

    };

    request.onerror = function() {

    };

    request.send();

    return jsonData;
}

Is the issue that the onload hasn’t finished running when the jsonData is returned? What would be the way around this? I tried adding the return after the JSON.parse but that didn’t seem to work either.

All I’m getting in log is undefined

I’d like to use one .js to load data, another to parse etc…

Thanks

Just extend your hypeDocument and then you can use the function in any Hype function.

hypeDocument.loadJSON = function (url){ your code here}

If you want to go the functions route you can add parameters into the events parameter. Usually an object with meta information about the context. But if you trigger yourself you can „use“ for your own purpose.

Also you cannot return the Json response right away. It is an asynchronous process so you can only provide a callback to be triggered or use the modern browser „await“ with promises or the even newer „async functions“.

Using an oldschool callback would be my suggestion.

edit: ups to late :wink:

XMLHttpRequest is by default (and recommend) asynchron. the value you’d like to return simply does not exist at this time …

the solution is to handle everything from within the callback.

///////

a workaround could be to store the received data (may be as data-attribute or local storage … etc), but this depends on the usecase

Thanks @MaxZieb and @h_classen

I’m trying to figure out how to structure my code and classes to make most sense and make it fairly modular. Basically I’ll be loading multiple json files with different structures in different projects and would like the parsing and loading data to different DOM objects to be fairly ‘modular’ from project to project.

Rather than changing the ‘main’ code every time and keeping taps on versions and mutations, having separate ‘libraries’ for how to deal with different data. Even if the data source changes from a json to database calls.

So how and where should the callback be placed?

@MaxZieb when you say extend HypeDocument, do you mean similar to here: Extend Tumult Hype with JavaScript: hypeDocument.extensions

I’ve never really needed to work with XMLHttpRequest so I’ll look into it now.

Thanks again

Was just knocking up something that kinda kept it hype’ish… using callback and hypeDocument.customData API

call json func ( on sceneload )

 function main(hypeDocument, element, event) {

	hypeDocument.customData.jsonUrl   = '${resourcesFolderName}/transimages.json';
  	hypeDocument.functions().loadJSON(  hypeDocument,element, event);
 
}

callback func ( seperate so we can do more if need be.

 function myFunction1(hypeDocument, element, event) {	
 console.log(hypeDocument.customData.jsonData)
}

loadJSON

 function loadJSON(hypeDocument, element, event) {	

 /*
  var request;
  request = new XMLHttpRequest();
  request.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
    
    jsonData = JSON.parse(request.responseText);
     myFunction1(jsonData);
     
    }
  };
 request.open("GET", hypeDocument.customData.jsonUrl, true);
 request.send();
 

 */
	// Define variables and receive jsonUrl from called script (i.e. main.js)
	var element_ = element[0];
	var jsonUrl = element[1];
	
	var jsonData;
	
    var request = new XMLHttpRequest();
  
    

    request.onload = function() {
        if (request.status >= 200 && request.status < 400) {

            jsonData = JSON.parse(request.responseText);
            //myFunction1(jsonData) 
            hypeDocument.customData.jsonData = jsonData // store data
            hypeDocument.functions().myFunction1(  hypeDocument,element, event); //callback
        } else {

        }

    };

    request.onerror = function() {

    };
  request.open('GET', hypeDocument.customData.jsonUrl, true);
    request.send();

}

event would be the variable to misuse in my opinion to keep it “hype-ish”. On the other hand, extending hypeDocument is also meanwhile “hype-ish”… at least I like to believe so :wink:

1 Like

True and I have done so myself. Just think this keeps things clean around hype functions and what they expect and what you need to do in them.

Excellent, thanks @MarkHunte, got it working and get the concept now.

@MaxZieb would love to see an example of how to deal with this by extending HypeDocument and what would the benefits be.

Thanks all

Hype Functions defined in the IDE have a fixed signature and are stored and need to be called forwarding some parameters… hypeDocument.functions().MYFUNCTION(hypeDocument, element, event);. As hypeDocument is created for each Hype document individually and the API is just an extendable object you can always just modify in an init-function “On Document Load” or an event function triggered by HypeDocumentLoad to define your functions directly under hypeDocument. This is done by assigning a function like

hypeDocument.MYFUNCTION = function(msg){ console.log(msg); }

Notice how you can define your specific function signature. This function is now available throughout your document.

I would recommend putting the function in the customData object, to not potentially conflict with API in the future.

hypeDocument.customData.MYFUNCTION = function(msg){ console.log(msg); }

The docs:

hypeDocument.customData
An object to put any user-defined data associated with the Tumult Hype Document.