0

I am learning angular and for my example using Firebase createUserWithEmailAndPassword for sign-up. This returns a promise which i have changed to observable using from.

In firebase minimum password length is 6 characters. When i provide 5 characters, in the console i see the error message but in my sign-up event, success message shows rather than error. What am i missing here?

AuthService

import * as firebase from 'firebase';
import { throwError, from } from 'rxjs';

export class AuthService{

    //user sign up, its a promise so listen for errors and log 
    signUpUser(email: string, password: string){
        //return an observable using from
        return from( 
            firebase.auth().createUserWithEmailAndPassword(email, password)
            .then(
                (authData) => {
                    //good
                    console.log("User created successfully with payload-", authData);
                    return authData;
                }
            )
            .catch(
                (error) => {
                    //error 
                    console.log(error); 
                    return throwError(error);;
                }
            )
        );
    }
}

Sign-up component

  onSignup(form: NgForm){
    const email = form.value.email;
    const password = form.value.password;
    this.authService.signUpUser(email, password).subscribe(
      (authData) => {
        alert("Signup successful");
        this.router.navigate(['/sign-in']);
      },
      (error) => {
        alert(error.message);
      }
    );
  }

Also i am using then in the authService method. How can i do .pipe(map(return authData.json()))?

Update 1:

Following helped and i am getting my error, on successful registration i am getting redirected to the sign-in view.

Convert promise to observable

AuthService

import { from  } from 'rxjs';

    signUpUserNew(email: string, password: string){
        var subscription = from(firebase.auth().createUserWithEmailAndPassword(email, password));
        return subscription;
    }

Sign-up Component

//property to hold result of sign-up error
  error = '';

  onSignup(form: NgForm){
    const email = form.value.email;
    const password = form.value.password;
    //this.authService.signUpUser(email, password);
    this.authService.signUpUserNew(email, password)
    .subscribe(
      (firebaseUser) => {
        console.log(firebaseUser);
        this.router.navigate(['/sign-in']);
      },
      (error) => {
        this.error = error.message;
      }
    );

  }

View

<h2>Register</h2>
<div class="row">
  <div class="col-xs-12 col-sm-10 col-md-8 col-sm-offset-1 col-md-offset-2">
    <form (ngSubmit)="onSignup(f)" #f="ngForm">
      <div class="form-group">
        <label for="email">Email</label>
        <input type="email" id="email" name="email" ngModel class="form-control" #email="ngModel" required email>
        <span class="help-block" *ngIf="!email.valid && email.touched">Please enter a valid email!</span>
      </div>
      <div class="form-group">
        <label for="password">Password</label>
        <input type="password" id="password" name="password" ngModel class="form-control" #password="ngModel" required minlength="6"> 
        <span class="help-block" *ngIf="!password.valid && password.touched && !password.errors?.minlength">Please enter a valid password!</span>
        <span class="help-block" *ngIf="!password.valid && password.touched && password.errors?.minlength">Password must be at least 6 characters long</span>
      </div>
      <p class="error" *ngIf="error">{{ error }}</p>
      <button class="btn btn-primary" type="submit" [disabled]="!f.valid">Sign Up</button>
    </form>
  </div>
</div>

Result

enter image description here

Pending

Now i still need help implementing pipe and map operators.

I am getting the following error on .json:

[ts] Property 'json' does not exists on type 'UserCredential'

  onSignup(form: NgForm){
    const email = form.value.email;
    const password = form.value.password;
    //this.authService.signUpUser(email, password);
    this.authService.signUpUserNew(email, password)
    .pipe(
      map(
        (firebaseUser) => {
          return firebaseUser.json();
        }
      )  
    )
    .subscribe(
      (firebaseUser) => {
        console.log(firebaseUser);
        this.router.navigate(['/sign-in']);
      },
      (error) => {
        this.error = error.message;
      }
    );

  }
learning...
  • 3,104
  • 10
  • 58
  • 96

1 Answers1

0

Firstly, I guess you should call fromPromise instead of from, so try the following:

import 'rxjs/add/observable/fromPromise';
import { Observable } from "rxjs/Observable";

signUpUser(email: string, password: string){
    //return an observable using fromPromise
    const obs$ = fromPromise( 
        firebase.auth().createUserWithEmailAndPassword(email, password)
    );

    // you can call .pipe() here, and it will return an observable
    return obs$.pipe(
       map(x => console.log('PUT YOUR MAP FUNCTION HERE.')),
       filter(x => console.log('Call filter() if you want'))
    );
}

And you can subscribe to this observable

const subscription = this.authService.signUpUser(email, password).subscribe(
  (firebaseUser) => {
    console.log('firebase user: ', firebaseUser);
    alert("Signup successful");
    this.router.navigate(['/sign-in']);
  },
  (error) => {
    alert(error.message);
  }
);
MattYao
  • 2,495
  • 15
  • 21
  • Unable to use your approach. Get an error on `fromPromise`. I have doen the imports as you have. Following link helped but now how to place pipe and map in there? Please see update 1 in the question. https://stackoverflow.com/questions/39319279/convert-promise-to-observable – learning... Jul 03 '18 at 05:06