🏠 Home 

Discussions » Development

Use GM.xmlHttpRequest response outside of the request

§
Posted: 2019-05-15

Use GM.xmlHttpRequest response outside of the request

Hi,

I just want to fetch currency exchange rates from an api returning JSON data. It works, but I can't use the value outside of the function.

// ==UserScript==
// @name         fetch currency exchange rate
// @namespace    graphen
// @version      1.0.0
// @author       Graphen
// @match        *example.com*
// @grant        GM.xmlHttpRequest
// @noframes
// ==/UserScript==
/* jshint esversion: 6 */
(function (doc) {
'use strict';
var ER, res;
function fetchExchangeRate(erUrl) {
GM.xmlHttpRequest ({
method :  'GET',
url:      erUrl,
headers : { 'Content-type' : 'application/json' },
onload :  function(xhr) {
res = JSON.parse(xhr.responseText);
//console.log("Got exchangerate USD --> EUR from server api.exchangeratesapi.io :");
//console.log(res.rates.EUR); // THIS WORKS
ER = res.rates.EUR;           // THIS DOESNT WORK (undefined outside)
return ER;                    // THIS DOESNT WORK (undefined outside)
// return res.rates.EUR;      // THIS DOESNT WORK (undefined outside)
},
onerror : function(xhr) {
//console.log("Error fetching JSON from xhr.");
return false;
}
});
}
fetchExchangeRate("https://api.exchangeratesapi.io/latest?base=USD&symbols=EUR");
//console.log(fetchExchangeRate("https://api.exchangeratesapi.io/latest?base=USD&symbols=EUR"));
console.log(ER);
})(document);

No matter if I make a copy to a variable or make a direct return - it always says "undefined" outside of the function.

woxxomMod
§
Posted: 2019-05-15
Edited: 2019-05-15

You can't use it outside of the function. The data is fetched asynchronously - GM.xmlHttpRequest basically registers a one-time event listener for "onload" event, immediately exits, then the rest of your code runs, then the data is fetched and the callback is invoked - which happens at some point in the future.

You can wrap GM.xmlHttpRequest into a Promise and switch to async/await syntax, look for tutorials and existing libraries here on GF.

§
Posted: 2019-05-17

Thanks for the good explanation, which now requires a not-so-pleasant solution from me :smile:

§
Posted: 2019-05-19

Simply put all the processing of data within onload function

§
Posted: 2019-05-19

@trespassersW Already thought about that but it's kind of ugly. To make sure the code runs I may have to duplicate all the stuff to do into onerror? I already started to learn about that asynchronous promise-resolve stuff, but it's not easy as beginner. First I wanted to get comfortable with objects, anonymous functions, callbacks, arrow style notation, ...

§
Posted: 2019-05-19

duplicate all the stuff to do into onerror? You may write a separate function for "duplicated stuff" and use in both event handlers

§
Posted: 2019-05-19

Ah right, I can get stuff "from outside in", apparently just not from inside out of the xmlHttpRequest.

Post reply

Sign in to post a reply.