0

I know this topic is covered in many questions. I have read many of them but couldn't translate the information to my situation as there are many frameworks for both Promises and making asynchronous HTTP requests. The more I read, the more confused I get. So I kindly ask for your help on this task. I will try to keep it as specific as possible.

This is what I want to do:

A user enters a search term and by submitting an api call is made to the Wikimedia API, requesting Wikipedia pages for that search term. This results in a list of pages, which can be normal pages or meta pages. I want to filter out the meta pages.

// the first call to the API, requesting the sources(pages)
axios.get(url, {params})
  .then(function (res) {
    const html = res.data[1].map((source) => {
      // here I want to filter meta pages 
      if (isNotMetaPage(source)) {
        return `
          <div class='sources_list_entry'>
            <p> ${source} </p>
          </div>
        `
      }
    }).join('')

In the function isNotMetaPage() I need to make another API call to Wikipedia, to get the page type (it is not included in the first request) and return true for a normal page and false for meta pages.

function isNotMetaPage (title) {

  const encodedTitle = encodeURI(title)
  const query = `?action=query&titles=${encodedTitle}&prop=revisions&rvprop=content&format=json&origin=*`
  let result

  axios.get(url.concat(query))
    .then(function (response) {
      const wikiPage = parseWikiMarkup(response)
      result = (wikiPage.type === 'page')
  })

  return result
}

Obviously, this function returns undefined, as the request is asynchronous and and result is returned before the API replies. When logging the result to the console inside the then-block it has the right value.

But how can I pause the execution until I have the result back? I read a lot that I should not make synchronous calls, but how can I avoid it here?

Appreciate your help!

Flip
  • 6,233
  • 7
  • 46
  • 75
  • 1
    You can't "pause" the javascript execution. Apparently you're starting to understand asynchronism and that your data will come later, at some point in time. Well, at this moment (in the `then`), when your data is available, call a testing function, passing it the data. For instance, `testTheResult(result)`. – Jeremy Thille Aug 11 '17 at 10:27
  • Yeah I understand the problem, just dont know how to solve it. I need the result of the call as without it, it returns undefined and the if block is never executed. – Flip Aug 11 '17 at 10:33
  • @Flip There is no solution. You have to defer the code that makes use of the result. – Bergi Aug 11 '17 at 10:49

1 Answers1

1

you can actually chain then() function, so in your case you would do it as follow:

axios.get(url, {params})
    .then(function (res) {
        const html = res.data[1].map((source) => {
        // here I want to filter meta pages 
        isNotMetaPage(source).then(function(isNotMeta) {
            if(isNotMeta){
                //do something asynchronously
            }
        });
}).join('')


function isNotMetaPage (title) {

    const encodedTitle = encodeURI(title)
    const query = `?action=query&titles=${encodedTitle}&prop=revisions&rvprop=content&format=json&origin=*`

    return axios.get(url.concat(query))
        .then(function (response) {
            const wikiPage = parseWikiMarkup(response);
            return (wikiPage.type === 'page');
    });
}
JohnnyAW
  • 2,866
  • 1
  • 16
  • 27