0

I have questions about promises. I'm just starting to deal with them and it's not that easy to understand!

I'm trying to setup an authentication system for my app.

RegisterPage

handleSubmit looks like that:

handleSubmit(event) {
  event.preventDefault();     
  const { user } = this.state;
  //some code here
  userActions.register(user);
}

UserActions

function register(user) {
  userService.register(user)
    .then(
      user => {
        success(user);
      },
      error => {
        failure(error.toString());
      }
    );
  function success(user) { return { type: "REGISTER_SUCCESS", user } }
  function failure(error) { return { type: "REGISTER_ERROR", error } }
}

UserService

function register(user) {
  const requestOptions = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(user)
  };

  return fetch(`/api/users/register`, requestOptions).then(handleResponse);
}

function handleResponse(response) {
  return response.text().then(text => {
      const data = text && JSON.parse(text);
      if (!response.ok) {  
          const error = (data && data.message) || response.statusText;
          return Promise.reject(error);
      }

      return data;
  });
}

Question 1. That code is "working" but not like I want. That way, even if the request success, I still can have error from the server, like duplicate username or something like that. I guess what I want is to return Promise.reject() not just if !response.ok but also if I have errors in the JSON returned right?

function handleResponse(response) {
  return response.text().then(text => {
      const data = text && JSON.parse(text);
      if (!response.ok) {  
          const error = (data && data.message) || response.statusText;
          return Promise.reject(error);
      }
      else if(data.errors) {
          return Promise.reject(data.message);
      }

      return data;
  });
}

Question 2. If everything's fine, should I return data or return Promise.resolve(data)? And why?

Cyril F
  • 1,247
  • 3
  • 16
  • 31
  • 3
    Where is React? – riv Aug 29 '18 at 19:15
  • 1
    1) Yes. Although you can also `throw` instead of `return Promise.reject`. And notice that you probably should check `response.ok` *before* using `.text()`. Also there's a `response.json()` method so that you don't need to call `JSON.parse` on the response text. 2) Use the simpler one. – Bergi Aug 29 '18 at 19:17
  • 1
    ok, it's not really a React question, you're right. – Cyril F Aug 29 '18 at 19:17
  • ` Promise.reject()` will be called either your response HTTP code contains 4xx or 5xx error codes or if you have error in your logic in then – madhu131313 Aug 29 '18 at 19:20
  • Hey, probably will be helpful: https://promisesaplus.com/ – dsych Aug 29 '18 at 19:21
  • 1
    (2) It would be the same thing, because if function passed to `then` returns a promise, then that promise is resolved to determine the result. Reading Promise docs (like in the link above) is helpful to get the general idea, but it's pretty technical and once you start using them more you will see that they're much more straightforward than it seems. – riv Aug 29 '18 at 19:21

1 Answers1

2

Checkout the documentation for fetch here: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Checking_that_the_fetch_was_successful

It seems you should be using .catch() to get server errors and just use throw new Error() for having errors.

You don't really need to use Promise.resolve or Promise.reject.

To help refactor what you have, you can try this

function register(user) {
  const requestOptions = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(user)
  };

  return fetch(`/api/users/register`, requestOptions).then(handleResponse);
}

function handleResponse(response) {
  return response.text()
     .then(text => {
       if (!response.ok) {
          const error = (data && data.message) || response.statusText;
          throw new Error(error);
       } else {
          const data = text && JSON.parse(text);
          return data;
       }
     })
     .catch(error => throw new Error(err));
}
superjisan
  • 1,604
  • 14
  • 15