0

I want to create my own fetch function to understand better XMLHttpRequest, Promises and Async/Await.

It doesn't seem like it's returning a promise as I get errors with then()

const fakeFetch = url => {
 const xhr = () => new Promise((resolve, reject) => {
  try {
   const x = new XMLHttpRequest();
   x.onreadystatechange = function() {
    const { readyState, status } = this;
    if (readyState === 4 && status === 200) {
     resolve(x.responseText);
    }
   }

   x.open('get', url);
   x.send();
  } catch(e) {
   reject(e);
  }
 })

 const _fetch = () => new Promise(async (resolve, reject) => {
  try {
   const response = await xhr();
   if (response !== undefined) resolve(response);
  } catch(e) {
   reject(e);
  }
 })

 _fetch();
}

fakeFetch('https://api.github.com/users')
.then(data => data.json())
.then(data => console.log(data));
totalnoob
  • 2,521
  • 8
  • 35
  • 69
  • The error seems pretty clear: you cannot use `await` unless it's in an `async` function. – Pointy Mar 01 '19 at 17:46
  • I've fixed it and it still returns undefined – totalnoob Mar 01 '19 at 17:51
  • To understand async/await better, you will need to understand that you [shall not](https://stackoverflow.com/q/45788934/1048572) [use it here](https://stackoverflow.com/q/43036229/1048572) [at all](https://stackoverflow.com/questions/47880415/what-is-the-benefit-of-prepending-async-to-a-function-that-returns-a-promise)! :-D – Bergi Mar 01 '19 at 17:56
  • @Bergi, I appreciate the suggestion, but I'm trying to understand the bigger picture and just trying to understand why the overall code isn't working properly. this isn't something I'd use in production. – totalnoob Mar 01 '19 at 18:22
  • Of course it's not (you'd use a standard polyfill), but still you really shouldn't pass an `async function` to `new Promise`, not even for fiddling around. – Bergi Mar 01 '19 at 18:29

1 Answers1

2

you're putting the async key word in the wrong place, it should be here :

let p = new Promise(async (resolve, reject) => {
                    ^^^^^

And to await for a function, it has to return a Promise : ( But in this use case you don't really need to await )

const fakeFetch = url => {
  const xhr = () => new Promise((resolve, reject) => {
    try {
      const x = new XMLHttpRequest();
      x.onreadystatechange = function() {
        const {
          readyState,
          status
        } = this;
        if (readyState === 4 && status === 200) {
          resolve(x.responseText);
        }
      }

      x.open('get', url);
      x.send();
    } catch (e) {
      reject(e);
    }
  })

  const _fetch = () => new Promise((resolve, reject) => {
    try {
      const response = xhr();
      if (response !== undefined) resolve(response);
    } catch (e) {
      reject(e);
    }
  })

  return _fetch();
}

fakeFetch('https://api.github.com/users')
  .then(data => console.log(data));
Taki
  • 17,320
  • 4
  • 26
  • 47
  • 1
    No, still don't use it there either - avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi Mar 01 '19 at 17:57
  • I've tried making changes to my code based off of your suggestions and I get an error with then() https://jsfiddle.net/k8oywhbn/ – totalnoob Mar 01 '19 at 18:19
  • remove `.then(data => data.json())` and return `_fetch()` ( updated answer ) – Taki Mar 01 '19 at 18:32