0

I am trying to write a website that gets an number input from the user as TRY (Turkish currency) and converts it to dollar. I want to do this with fetch() in js. Here is my code. If I write console.log(data.tr.rate) instead of rate = data.tr.rate, it prints dollar's current rate which exactly what I want, however when I write the code below it prints "undefined".

        var rate;
        const m_currency = fetch('http://www.floatrates.com/daily/usd.json').then(res => res.json()).then(function(data){
            
            rate = data.tr.rate;

            
        });
        console.log(rate);
  • Does this answer your question? [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Heretic Monkey Aug 21 '20 at 11:59

2 Answers2

1

The fetch API is asynchronous, this means that the console.log will occur before your fetch sends a response back.

var rate; // First
const m_currency = fetch('http://www.floatrates.com/daily/usd.json').then(res => res.json()).then(function(data) {
  rate = data.tr.rate; // Third
});
console.log(rate); // Second
PotatoParser
  • 1,008
  • 7
  • 19
  • How can I make console.log(rate) function wait for the fetch operation conclude? –  Aug 20 '20 at 21:09
  • You would have to place the `console.log(rate)` within the `function(data) {rate = data.tr.rate; // Third})` as unfortunately, the fetch API is not synchronous. – PotatoParser Aug 20 '20 at 21:11
1

The code where you request the rates JSON is a Promise, which is asynchronous code. You should execute all your code inside the then block, anything you do outside that block, may execute earlier, so the value of the variable cannot be told.

If you want to fetch synchronously to assign to a variable, you may use an async function and await the resolution of the Promise, but async functions are Promises themselves, that you must run as the fetch function. Here's an example:

async function get_rate() {
    var res = await fetch('http://www.floatrates.com/daily/usd.json');
    var data = await res.json();
    return data.tr.rate;
};

// works
get_rate().then((rate) => { console.log(rate); });

// doesn't work, no error but it's a promise and not a value
console.log(get_rate());
Marc Sances
  • 2,402
  • 1
  • 19
  • 34
  • I want to ask a question. So if you want to create an object or simply an integer, by using fetch() is it possible for you to assign this integer or this object to the data that you fetch(). For instance, how does someone create an object and use it in his/her program if he/she filled the object with datas that was fetched? –  Aug 20 '20 at 21:23
  • You can assign it in the "then" code block. You could run the promise inside a class and modify ``this``. To do so, you'll have to ``.bind(this)`` at the end of the promise, see this: [Binding a promise handler function to an object](https://stackoverflow.com/questions/16435167/binding-a-promise-handler-function-to-an-object) since it is out of the scope of the question I guess. – Marc Sances Aug 20 '20 at 21:25