1

I am new to Javascript and trying to understand how promises work. I have written the below code to call a REST API and resolve the response.

const buyFlightTicket = () => {
    return new Promise( (resolve, reject) => {
        setTimeout( () => {
            let commentResponse = fetch('https://jsonplaceholder.typicode.com/comments/1'); 
            commentResponse
                .then(response => {
                    if (response.status == 200) {
                        resolve(response.json());
                    } else {
                        reject("Failed to fetch comment: " + response.statusText);
                    }
                })
                .reject("Failed to fetch comment");
        }, 3000);
    })
}

buyFlightTicket()
.then( (responseData) => console.log(responseData))
.catch( (error) => console.log(error));

I am able to log the response data but I am getting Error: Unknown error just before the response is being logged to the console.

What is causing this error?

Also, how do i rewrite this code using callbacks without using Promise?

java_geek
  • 17,585
  • 30
  • 91
  • 113
  • 1
    I think you must use .catch("Failed to fetch comment") instead of .reject("Failed to fetch comment"). – soltex Jul 20 '20 at 13:22
  • @soltex Thanks. I figured this out after i posted. – java_geek Jul 20 '20 at 13:28
  • 1
    Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! Immediately `resolve` after the `setTimeout`, and put the rest in a `then` callback. – Bergi Jul 20 '20 at 14:27
  • "*how do i rewrite this code using callbacks without using Promise?*" - why would you want to do that? Also, it's impossible, since `fetch` returns a promise you'll have to use. – Bergi Jul 20 '20 at 14:28
  • @Bergi Without the anti-pattern, can you please tell me how I would re-write this? – java_geek Aug 14 '20 at 14:25

2 Answers2

2

You should use the catch, not .reject

            commentResponse
                .then(response => {
                    if (response.status == 200) {
                        resolve(response.json());
                    } else {
                        reject("Failed to fetch comment: " + response.statusText);
                    }
                })
                .catch(() => "Failed to fetch comment");

Terence Cheng
  • 594
  • 2
  • 4
0

you can use fetch, which also return a promise

const buyFlightTicket = () => {
    let commentResponse = fetch('https://jsonplaceholder.typicode.com/comments/1'); 
    return commentResponse
        .then(response => {
            if (response.status == 200) {
                return (response.json());
            } else {
                return new Error("Failed to fetch comment: " + response.statusText);
            }
        })
}

buyFlightTicket()
.then( (responseData) => console.log(responseData))
.catch( (error) => console.log(error));

If the browser doesn't support the Promise, you can add the polyfill or you can use the xhr

    var buyFlightTicket = function(cb, errorCb) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://jsonplaceholder.typicode.com/comments/', true);
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4){
                if (xhr.status === 200){
                  cb(xhr.responseText)
                } else {
                  errorCb(xhr.statusText);
                }
            }
        };


        xhr.send(null);
        xhr.onerror = function (e) {
            console.error(xhr.statusText);
        };
        console.log('end')
    }
    buyFlightTicket(successCb, errorCb)
    function successCb(res) {
        console.log(res);
    }
    function errorCb(err) { console.log(err) }
Terence Cheng
  • 594
  • 2
  • 4