3
\$\begingroup\$

One of my react component's methods is using an async fetch() internally. After fetching the response from the server, it is being converted to JSON, then I perform a check on that JSON string. Finally, I return the result wrapped in a new promise. Here is the code:

fetchCalendarData(offset, length) {
 return fetch(this.props.Uri + '?offset=' + offset + '&length=' + length)
 .then(response => response.json())
 .then((result) => {
 if (result.hasOwnProperty('redirect_to_login') && result.redirect_to_login == true) {
 window.location.reload(window.globalAppState.base_url + "/login");
 }
 return Promise.resolve(result);
 })
 .catch(() => {
 return Promise.reject('FAILURE');
 });
}

When I call the method, I do it like this:

this.fetchCalendarData(0, 6).then((fetched_calendar_data) => {
 this.calendar_data = fetched_calendar_data;
});

The code works, but I am not familiar with promise based flow at all, and those 3 return statements look a little weird to me. I also read about the promise constructor antipattern but am not sure if that applies here. And, is it necessary to return the result wrapped in a new promise, at all?

asked Jan 8, 2019 at 23:00
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

but am not sure if that applies here. And, is it necessary to return the result wrapped in a new promise, at all?

Yes, that applies here.

No, returning Promise.resolve() is not necessary. .then() returns a new Promise object. Use

return result

within the function passed to .then().

Note, a value returned from .catch() results in a resolved Promise. Depending on how errors are handled an error could be thrown (withing {} of a function).

this.fetchCalendarData(0, 6).then((fetched_calendar_data) => {
 this.calendar_data = fetched_calendar_data;
});

should include the second parameter to .then() to handle potential error

.then((fetched_calendar_data)=>{}, err=>{/* handle error */})

given then Promise.reject() is returned from .catch(), or .catch() should be chained to .then()

.then((fetched_calendar_data)=>{}
.catch(err=>{/* handle error */})

fetchCalendarData(offset, length) {
 return fetch(this.props.Uri + '?offset=' + offset + '&length=' + length)
 .then(response => response.json())
 .then(result => {
 if (result.hasOwnProperty('redirect_to_login') 
 && result.redirect_to_login == true) {
 window.location.reload(window.globalAppState.base_url + "/login");
 }
 return result;
 })
 .catch(() => {
 throw new Error('FAILURE');
 });
}
this.fetchCalendarData(0, 6)
.then(fetched_calendar_data => {
 this.calendar_data = fetched_calendar_data;
})
.catch(err => console.error(err));
answered Jan 9, 2019 at 1:21
\$\endgroup\$
2
  • \$\begingroup\$ I really appreciate your comprehensive review! Is it just a matter of style if you use .then(resolve_callback, reject_callback) or .then(resolve_callback).catch(reject_callback) ? \$\endgroup\$ Commented Jan 9, 2019 at 9:53
  • 1
    \$\begingroup\$ @Benni There is a difference, see When is .then(success, fail) considered an antipattern for promises? \$\endgroup\$ Commented Jan 9, 2019 at 17:01

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.