0

After reaching to tons of previous related questions here and on many other sites, I still cannot understand if I am writing an anti-pattern with the following code:

function signUp(email: string, password: string): Observable<UserCredential> {
    return from(
      createUserWithEmailAndPassword(email, password).then(
        (authRes) => {
          createNewUserDocument(authRes);
          return authRes;
        }
      )
    );
}

The createNewUserDocument is an async function. The point is I want to call it after the user signs up, and I want to return an Observable<UserData> not Observable<Promise<UserData>> (nor Promise<UserData>), hence I cannot make the signup function async and just use 2 await calls sequentially.

Also, should I put async before then's handler and await before the createNewUserDocument call, or is it not necessary? (code seems to work as it is)

  • Well, antipattern or not, it *doesn't work* if your intention was to wait for `createNewUserDocument` as well. Also you're not handling errors from it. – Bergi Aug 29 '21 at 21:54
  • [Yes, you probably should handle errors](https://stackoverflow.com/q/32384449/1048572). – Bergi Aug 29 '21 at 22:03

1 Answers1

1

Well, antipattern or not, it doesn't work if your intention was to wait for createNewUserDocument as well. Also you're not handling errors from it.

Should I put async before then's handler and await before the createNewUserDocument call

Yes, that would work. However, mixing async/await with then is weird. If you want to use await already, use it in place of every then call where possible:

function signUp(email: string, password: string): Observable<UserCredential> {
  async function create() {
    const authRes = await createUserWithEmailAndPassword(email, password);
    await createNewUserDocument(authRes);
    return authRes;
  }
  return from(create());
}

If you wanted to use only .then(), chaining still works:

function signUp(email: string, password: string): Observable<UserCredential> {
  return from(
    createUserWithEmailAndPassword(email, password).then(authRes => {
      return createNewUserDocument(authRes).then(() => {
        return authRes;
      });
    })
  );
}

The inner .then() might not even be necessary if createNewUserDocument returns a promise for the authRes.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375