0

I'm trying to call the Wikipedia API to retrieve a random title of a page. I want to save the title of the page in a variable for later use but I can not find a way to resolve the promise. I keep getting ZoneAwarePromise returned. I'm very new to promises and typescript in general, is there any way to solve this?

I've tried adding await on the promises, but I still get returned promises.

async getPage() : string {
    var url = "https://en.wikipedia.org/w/api.php";
    var params = {
        action: "query",
        generator: "random",
        rnnamespace: "0",
        format: "json",
        list: "random",
        rnlimit: "1"
    };

    url = url + "?origin=*";
    Object.keys(params).forEach(function(key){url += "&" + key + "=" + params[key];});
    return await fetch(url)
        .then (response => response.json())
        .then(data => data.query.random[0].title)
        .catch(function(error){console.log(error);});
}

I expect the output to just be the title pulled, I can only seem to console.log the title but I want to save it to a variable for use in other functions.

Grant MBB
  • 11
  • 1
  • 1
  • 1
  • `await` goes in the *callers* of your function, not inside your function. Those calling functions must be `async` as well. – Jared Smith Sep 06 '19 at 16:24
  • "*I can not find a way to resolve the promise.*" - there is none, a promise resolves by itself. All you can do (with `then` or `await`) is wait for that. – Bergi Sep 06 '19 at 16:29

2 Answers2

0

do this then

async getPage() : string {
    var url = "https://en.wikipedia.org/w/api.php";
    var params = {
        action: "query",
        generator: "random",
        rnnamespace: "0",
        format: "json",
        list: "random",
        rnlimit: "1"
    };

    url = url + "?origin=*";
    Object.keys(params).forEach(function(key){url += "&" + key + "=" + params[key];});

    const title = await fetch(url)
        .then (response => response.json())
        .then(data => data.query.random[0].title);
           .catch(function(error){console.log(error);});

   // do whatever you want with title here  

}

ehab
  • 7,162
  • 1
  • 25
  • 30
0

Async functions always return promises. The reason that async/await exists is to make the syntax for working with promises easier. Additionally, you're mixing async/await with .then, and while this is technically possible it will make the code harder to understand and is almost never needed. Pick one style (i'd recommend async/await), and use that.

So your getPage function should look something like this:

async getPage(): string {
    let url = "https://en.wikipedia.org/w/api.php";
    const params = {
        action: "query",
        generator: "random",
        rnnamespace: "0",
        format: "json",
        list: "random",
        rnlimit: "1"
    };

    url = url + "?origin=*";
    Object.keys(params).forEach(function(key){
      url += "&" + key + "=" + params[key];
    });

    try {
      const response = await fetch(url);
      const data = await response.json();
      return data.query.random[0].title;
    } catch (error) {
       console.log(error)
    }
}

And as mentioned, getPage will return a promise. To get access to the value in the promise, either use .then

getPage().then(title) => console.log('title', title));

or async/await

async someFunction (){
  const title = await getPage();
  console.log('title', title);
}
Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98