6

I am a bit confused with how to properly use fetch. It seems to resolve even when I get an error status back. Is the below code correct (wrapping the fetch in another promise)?

function a(url, config) {
  if (!config)
    config = {};

  config = Object.assign(config, {
    headers: {
      'content-type': 'application/json;charset=utf-8'
    }
  })
  return new Promise(
    function(resolve, reject) {
      fetch(url, config).then(
        function(res) {
          if (res.status == 200 && res.ok) {
            console.log("Promise resolved")
            resolve(res);
            return;
          }
          console.log("Promise rejected")
          reject(res);
        },
        function(rej) {
          console.log("promise rejected")
          reject(rej);
        }
      )
    }
  )
}

function b() {
  a('/test').then(
    function(res) {
      console.log('success');
      console.log(res)
    },
    function(rej) {
      console.log('Rejected');
      console.log(rej)
    }
  )
}

b();
(The above code should run fine in chrome via console... just copy/paste )
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
Goblinlord
  • 3,290
  • 1
  • 20
  • 24
  • 1
    if `fetch` is the fetch that exists in all modern browsers, it, as you clearly know, returns a promise. So there's no need to wrap it in a promise, it only confuses things – Jaromanda X Dec 06 '15 at 10:25
  • Actually... it resolves even with error status like 400. Hence, if I want the called to know it got an error code... I need to wrap and reject if its not ok/200. Though... at the moment... the above code works as expected (b runs reject)... I am looking at my code to try and rewrite the above to match it. Either way, the above was just an example and fetch was just what I could use to create a promise easy to demonstrate. – Goblinlord Dec 06 '15 at 10:26
  • 1
    Looks good, with this code you get "Promise rejected", "Rejected". As expected. Not clear what the problem is. – dfsq Dec 06 '15 at 10:28
  • Yeah sorry, I tried to write a quick example and actually the example is working. I am looking at my app code to try and make it match right now. – Goblinlord Dec 06 '15 at 10:29
  • @JaromandaX Again... how can I do this and reject on anything that is not 200? By default fetch doesn't reject if its not 200. When I use fetch I am expecting resolve to return something I can use. At the moment, I can't even recreate what I was seeing and my code seems to be working as expected in my app though. Still looking into it – Goblinlord Dec 06 '15 at 10:38
  • @Goblinlord - as your example code works correctly (according to you) how can I answer that question? – Jaromanda X Dec 06 '15 at 10:40
  • @Goblinlord Check my answer for how to reject promise for non-200 statuses. – dfsq Dec 06 '15 at 10:41
  • I will rewrite the question a bit to match the answer... as my question didn't originally relate to this. I would rather it be more useful if someone looks at it later =/. – Goblinlord Dec 06 '15 at 10:45
  • don't worry, it's been asked many times before – Jaromanda X Dec 06 '15 at 10:48
  • "*Is it correct to wrap the fetch in another promise?*" - no, that's the [`Promise` constructor antipattern](http://stackoverflow.com/q/23803743/1048572). – Bergi Dec 06 '15 at 13:12
  • Many years later... looking at this question hurts my heart. I obviously didn't know what I was doing. I think this was one of the problems that helped me understand promises though. Looks so clear to me now~ Simply return fetch, and use `then` callback and throw if not 200 if it should be an error. Simple~ ^^ – Goblinlord May 03 '21 at 12:43

1 Answers1

2

If you want to reject from success callback you need to do it explicitly by either returning rejected promise, e.g. return Promise.reject('error occurred'); or by throwing.

Additionally, you should not abuse Promise constructor in your case since fetch already returns promise object:

function a(url, config) {
    if (!config)
        config = {};

    config = Object.assign(config, {
        headers: {
            'content-type': 'application/json;charset=utf-8'
        }
    });

    return fetch(url, config).then(
        function(res) {
            if (res.status == 200 && res.ok) {
                console.log("Promise resolved")
                return res.json();
            }
            console.log("Promise rejected");
            throw 'promise rejected';
        },
        function(rej) {
            console.log("promise rejected");
            throw 'promise rejected';
        }
    );
}
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • I can't delete the question as the code is actually working as expected =/. Thanks for the suggestions for the throws instead of the what I was doing. – Goblinlord Dec 06 '15 at 10:43