-1

I can't get a Promise to return a string after having called .then on the fetch call.

I'm accessing a public API and retrieving the rates property from the JSON response.

{
    "base": "EUR",
    "rates": {
        "CAD": 1.4867
    },
    "date": "2021-03-16"
}

I have a private method that calls fetch on this endpoint and returns a Promise type.

    private getCadCurrency(): Promise<Currency> {
        return fetch('https://api.ratesapi.io/api/latest?symbols=CAD')
                .then(response => response.json())
                .then(res => {
                    return res as Currency
                });
    }

Currency interface

interface Currency {
    base: string,
    rates: string,
    date: string
}

When I make a call to getCadCurrency() and then chain it with a .then call I seem to still get Promise object instead of the Rate value.

let test = this.getCadCurrency().then(x => { return x.rates });
console.log(test);

When I inspect test in the Developer Tools I find that it reports a mixed state - probably when it's originally pending and then its final results.

enter image description here

What do I need to do to return the rates string?

Ryan B
  • 320
  • 2
  • 6
  • 18
  • You cannot return the actual result. Your function will return BEFORE the value is available. All you can do here is return the promise and the caller then uses `.then()` or `await` on the promise to get the eventual value. That is how asynchronous coding works in Typescript/Javascript. – jfriend00 Mar 17 '21 at 06:25
  • 1
    Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – jfriend00 Mar 17 '21 at 06:26
  • `this.getCadCurrency().then(...)` returns a new promise. You HAVE to use the value inside the `.then()` callback or use `await` instead. The only way you ever get a value out of a promise is with `.then()` (where you use the value inside the `.then()` callback) or where you use `await` on the promise. – jfriend00 Mar 17 '21 at 06:56
  • @jfriend00 - I call .then(x => { return x.rates}), why is this not "use"ing the value inside the callback? I had given the linked article a read, but was still confused about how to reach my goal. – Ryan B Mar 17 '21 at 14:28
  • Each `.then()` creates a new promise and what `.then(x => { return x.rates}),` does is set the resolved value of the new promise to `x.rates`. That's a perfectly fine thing to do, but you still have a promise. Whoever is receiving that promise will have to use `.then()` or `await` on that new promise and then "using the value in the `.then()` handler" means to actually do whatever your final action is with the value (not passing it on to someone else). You can also call a function from within the `.then()` handler and pass the resolved value as an argument to that function. – jfriend00 Mar 17 '21 at 15:14
  • @jfriend00 - thanks for the clarification. Passing the resolved value as a function argument was a missing piece. – Ryan B Mar 17 '21 at 17:45

1 Answers1

1

Use async/await instead of callbacks. https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await

private async getCurrency() {
  ...
}

async otherFunction() {
  let test = await getCurrency();
}
btin
  • 306
  • 2
  • 9
  • Not sure why you downvoted, this is quite literally the standard way to do it. – btin Mar 17 '21 at 06:37
  • thanks for your answer. I upvoted because this strategy and the MDN docs got me to where I needed to be, but it doesn't answer the original question about why the Promise won't resolve. – Ryan B Mar 17 '21 at 17:44