Asynchronous Javascript Requests: Difference between revisions
(Created page with "{{Languages|Javascript}} There are two APIs for making asynchronous requests from HTML5 javascript to MTScript. The first is a reimplementation of the old {{func|XMLHttpReq...") |
m (Replaced source tages with syntaxhighlight) |
||
Line 7: | Line 7: | ||
Assume the following macro is named <code>myMacro</code> and is on a library token called <code>lib:myLib</code>. | Assume the following macro is named <code>myMacro</code> and is on a library token called <code>lib:myLib</code>. | ||
< | <syntaxhighlight lang="mtmacro"> | ||
[h: broadcast(macro.args)] | [h: broadcast(macro.args)] | ||
[h: val=1d20] | [h: val=1d20] | ||
[r: "Arguments: "+macro.args] | [r: "Arguments: "+macro.args] | ||
[r: "d20: "+val] | [r: "d20: "+val] | ||
</ | </syntaxhighlight> | ||
The following javascript will execute the macro and spit its result to the chat box. | The following javascript will execute the macro and spit its result to the chat box. | ||
< | <syntaxhighlight lang="js"> | ||
function getValue(valueCallback) { | function getValue(valueCallback) { | ||
let x = new XMLHttpRequest() | let x = new XMLHttpRequest() | ||
Line 29: | Line 29: | ||
getValue((response)=>{console.log(response)}) | getValue((response)=>{console.log(response)}) | ||
</ | </syntaxhighlight> | ||
Line 36: | Line 36: | ||
Assume the following macro is named <code>myJson</code> and is on a library token called <code>lib:myLib</code>. | Assume the following macro is named <code>myJson</code> and is on a library token called <code>lib:myLib</code>. | ||
< | <syntaxhighlight lang="mtmacro"> | ||
[h: val=1d20] | [h: val=1d20] | ||
[h: result = "{}"] | [h: result = "{}"] | ||
Line 42: | Line 42: | ||
[h: result=json.set(result, "value", val)] | [h: result=json.set(result, "value", val)] | ||
[r: result] | [r: result] | ||
</ | </syntaxhighlight> | ||
This can easily be retrieved by using the second asynchronous javascript API: {{func|fetch}} | This can easily be retrieved by using the second asynchronous javascript API: {{func|fetch}} | ||
< | <syntaxhighlight lang="javascript"> | ||
let x = fetch("macro:myJson@lib:myLib", {method: "POST", body: "someTarget"}) | let x = fetch("macro:myJson@lib:myLib", {method: "POST", body: "someTarget"}) | ||
x.then((r)=> | x.then((r)=> | ||
Line 64: | Line 64: | ||
} | } | ||
) | ) | ||
</ | </syntaxhighlight> | ||
As usual with javascript, if we are happy with <code>async</code> functions, we can clean that up considerably. Here is an example fetching the same macro as a string instead of calling it. (Note that <code>Allow URI access</code> must be enabled on the lib token). | As usual with javascript, if we are happy with <code>async</code> functions, we can clean that up considerably. Here is an example fetching the same macro as a string instead of calling it. (Note that <code>Allow URI access</code> must be enabled on the lib token). | ||
< | <syntaxhighlight lang="javascript"> | ||
async function | async function getResyntaxhighlight() { | ||
let r = await fetch("lib://myLib/macro/myJson") | let r = await fetch("lib://myLib/macro/myJson") | ||
// We cannot ask for the body as json, as it is just a UTF8 string. | // We cannot ask for the body as json, as it is just a UTF8 string. | ||
Line 75: | Line 75: | ||
console.log(body) | console.log(body) | ||
} | } | ||
</ | </syntaxhighlight> | ||
Note that <code>await</code> will throw an exception if the awaited promise fails. Use <code>try/catch</code> if there is a risk of the macro failing in some way. | Note that <code>await</code> will throw an exception if the awaited promise fails. Use <code>try/catch</code> if there is a risk of the macro failing in some way. |
Revision as of 18:13, 14 July 2022
Languages: English
There are two APIs for making asynchronous requests from HTML5 javascript to MTScript.
The first is a reimplementation of the old XMLHttpRequest(). It is unlikely you'll want to use this directly, but it exists to let older javascript libraries function. Also, the second API is implemented on top of XMLHttpRequest(), so if you need lower level access, this is the way to go.
Assume the following macro is named myMacro
and is on a library token called lib:myLib
.
[h: broadcast(macro.args)]
[h: val=1d20]
[r: "Arguments: "+macro.args]
[r: "d20: "+val]
The following javascript will execute the macro and spit its result to the chat box.
function getValue(valueCallback) {
let x = new XMLHttpRequest()
x.open("POST", "macro:myMacro@lib:myLib", true) // can use false for synchronous requests, but it is discouraged
x.onreadystatechange = function() { // runs at each change of readystate, we're done when we hit state 4
if (x.readyState == 4) {
valueCallback(x.response)
}
}
x.send("arguments")
}
getValue((response)=>{console.log(response)})
Often, you'll want to return structured data from the macro, which can be provided like so.
Assume the following macro is named myJson
and is on a library token called lib:myLib
.
[h: val=1d20]
[h: result = "{}"]
[h: result=json.set(result, "target", macro.args)]
[h: result=json.set(result, "value", val)]
[r: result]
This can easily be retrieved by using the second asynchronous javascript API: fetch()
let x = fetch("macro:myJson@lib:myLib", {method: "POST", body: "someTarget"})
x.then((r)=>
{
r.json().then((result)=>{
console.log(result.value)
},
(error)=>{
console.log("Response not valid json")
console.log(error)
})
},
(e)=>
{
console.log("macro invocation failed")
console.log(e)
}
)
As usual with javascript, if we are happy with async
functions, we can clean that up considerably. Here is an example fetching the same macro as a string instead of calling it. (Note that Allow URI access
must be enabled on the lib token).
async function getResyntaxhighlight() {
let r = await fetch("lib://myLib/macro/myJson")
// We cannot ask for the body as json, as it is just a UTF8 string.
let body = await r.text()
console.log(body)
}
Note that await
will throw an exception if the awaited promise fails. Use try/catch
if there is a risk of the macro failing in some way.