2

Today I am struggling with a fetch issue in my react native app. I would like my user to login straight after he registers. In order to do that I have one function to fetch the signUp and another one to fetch the login. The problem is that when in the view I click on the register() button, only the signUp fetch is called. Though, if I click a second time on the button then both the signup and the login fetch are called but an error occurs on the signup because the user has already been added to the database. So, I would like to be able to chain two fetch, one after another. Here is my code :

The API helper class:

    const Api = {

  signUp(user) {
    return new Promise((resolve, reject) =>
    {
      console.log(Constant.default.apiUrl);
      fetch(Constant.default.apiUrl + '/signup', {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(user)
      })
        .then(response => response.json())
        .then(responseJson => {
          if (responseJson.success) {
            console.log(responseJson.userData);
            resolve(responseJson.userData);
          } else {
            reject(responseJson);
          }
        })
        .catch(err => console.log(err));
    });
  },

  login(user) {
    return new Promise((resolve, reject) => {
      fetch(Constant.default.apiUrl + '/login', {
        method : 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(user)
      })
        .then(response => response.json())
        .then(responseJson => {
          console.log("responsejson " + responseJson);
          console.log("laaaa");
          if (responseJson.success) {
            resolve(responseJson.userData);
          } else {
            reject(responseJson);
          }
        })
        .catch(err => console.log("catch login" + err))
    })
  }
};

export default Api;

The register function (when I click register button):

register () {

    if (this.state.password.length > 3 && this.state.password === this.state.confirmPassword) {
      var user = {
        firstName: this.props.firstName,
        lastName: this.props.lastName,
        emailAddress: this.state.emailAddress,
        password: this.state.password,
      };

      Api.signUp(user)
        .then(result => {
          console.log("sign up result : " + JSON.stringify(result));
          return {
            emailAddress : user.emailAddress,
            password : user.password
          };
           })
        .then(loginUser => {
          Api.login(loginUser)
            .then(result => {
              console.log("login result " + JSON.stringify(result));
            })
            .catch(resultErr => console.log(resultErr));
        })
        .catch(resultErr => console.log(resultErr));

    } else {
      this.setState({error: true,
        errorMessage: 'Veuillez remplir les champs correctement'});
    }
  };

Please help me figure out why I have to click twice on register() button.

EDIT:
When I click once, nothing happens in the console but the user is added to the database. The second time, I see this:

enter image description here

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • I forgot to mention that the login and the signup work perfectly separately ;) – Margot Le Rouzic Oct 29 '16 at 20:18
  • Quick guess... the response.json() call in the signup method is not being fulfilled before the Promise.reject fires on the first click, and on the second click it has fulfilled, thus progressing to the login method. It seems similar to [this post...](http://stackoverflow.com/questions/29473426/fetch-reject-promise-with-json-error-object) – Zany Cadence Oct 29 '16 at 22:07
  • If you catch errors for logging/debugging, don't forget to re-throw them. – Roamer-1888 Oct 29 '16 at 22:15
  • @ZanyCadence - I don't think this code does that - and if it did, it wouldn't be using the same signup Promise on the second click as was used on the first, that's not how this code is written – Jaromanda X Oct 30 '16 at 00:30
  • @MargotLeRouzic - not the problem, but you've fallen for the [promise constructor anti-pattern](http://stackoverflow.com/a/23803744/5053002) – Jaromanda X Oct 30 '16 at 00:34
  • What's not evident is what you see in the console and networks tab of the browser - anything useful there? – Jaromanda X Oct 30 '16 at 00:36
  • you're also, as pointed out by Roamer-1888, "swallowing" errors in Api, so you'll never get errors to `.catch` in `register` function anyway – Jaromanda X Oct 30 '16 at 00:42
  • @MargotLeRouzic - your code, cleaned up, which is far easier to read in my opinion as well - http://pastebin.com/pd9sdZRS - this wont fix the problem, but may help find the problem – Jaromanda X Oct 30 '16 at 00:59
  • Thanks a lot for your answers !! @JaromandaX With your code, I still have to click twice, but it is really clean because the return statement helped me to resolve a warning. When I click for the first time, nothing happens in the console but the user is added to the db. The second time, something appears in my console. I edited my post to show this. – Margot Le Rouzic Oct 30 '16 at 07:12
  • The expected order is : apiHelper.js:20, apiHelper.js:32, signupSceneContainer.js:102, apiHelper.js:60, apiHelper.js:61, signupSceneContainer.js:110; but the log shows : apiHelper.js:32, signupSceneContainer.js:102, apiHelper.js:20, apiHelper.js:60, apiHelper.js:61, signupSceneContainer.js:110. Try adding something to every `console.log()` statement so you can distinguish between entries arising from "1st click" and "2nd click". – Roamer-1888 Oct 30 '16 at 13:34
  • To do that, you will need to pass a value to `register()`, `signUp()` and `login()` (closure will do the rest). Don't be tempted into relying solely on an outer variable. – Roamer-1888 Oct 30 '16 at 14:46
  • After long hours lost with my emulator ios on react-native, I tried with my real iphone and it works ... I really don't know why. If you have some suggestions about this bug, tell me .. Thank you again for your help :) – Margot Le Rouzic Nov 01 '16 at 20:35

0 Answers0