0

I have a login button in my app, when a user clicks on it, the request is sent to the service file, from there firebase looks after the authentication process. My question is if the login is scucessfull and token is set, then i want to use return 'Login Successful' and then print this in the frontend to the client to notify that login is successful. I've tried various ways but couldn't solve this.

Component.ts file

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { AuthService } from '../auth.service';

@Component({
   selector: 'app-login',
   templateUrl: './login.component.html',
   styleUrls: ['./login.component.scss']
})

export class LoginComponent implements OnInit {

    constructor(
        private authService:AuthService
    ) { }

    ngOnInit() {
    }

    login(form: NgForm) {
        const email = form.value.input_emailid;
        const password = form.value.input_password;

        this.authService.loginUser(email,password);    

    }

}

My service file(AuthService.ts)

import * as firebase from 'firebase';
import { Router } from '@angular/router';
import { Injectable } from '@angular/core';

@Injectable()
export class AuthService {

constructor(
    private router:Router
) {}

token: string;

loginUser(email: string,password: string) {
  firebase.auth().signInWithEmailAndPassword(email,password)
    .then(
      (response) => {
        this.router.navigate(['/']);
        firebase.auth().currentUser.getIdToken()
        .then(
          (token: string) => {
            this.token = token;
            // Want to return the below return statement
            return 'Login Successful';

          }
        )
      }
    ).catch(
      error => console.log(error)
  )
}
sid
  • 365
  • 2
  • 11
  • 1
    Well instead of redirecting the user in the service you should return an observable that indicate success or failure and do actions in the component. Or you can keep the redirection in the service and add query parameter to indicate to display a notification. – JEY Mar 05 '19 at 08:16

3 Answers3

3

When using Rx you don't return values like that, instead you publish a change to a subject and observe it in your component.

In your service:

import { BehaviorSubject } from 'rxjs';
// ...
private isLoggedInSubject = new BehaviorSubject<boolean>(false);
isLoggedIn$ = this.isLoggedInSubject.asObservable();

// ...
this.token = token;
this.isLoggedInSubject.next(true);

In your component:

this.authService.isLoggedIn$.subscribe(loggedIn => this.message = loggedIn ? 'Logged In' : 'Failure');
this.authService.loginUser(email,password);
Markus Dresch
  • 5,290
  • 3
  • 20
  • 40
0

You should define your loginUser() as an observable and subscribe it in your Login component. So that when authentication is completed, you return the login successful, and component subscribing it will get the notification.

Right now it's not working, because authentication process is (might be, not sure) asynchronous and till the value is returned this.authService.loginUser(email,password); has been finished.

emkay
  • 777
  • 8
  • 19
0

You can use observable of RXjs in your service and component.See the code below. In your component:

    login(form: NgForm) {
            const email = form.value.input_emailid;
            const password = form.value.input_password;

            this.authService.loginUser(email,password).subscribe(
                 (result) => {
                   if(result){
                      // do what you want here
                    }else{
                      // show error message here
                     }
                  }
              });    

        }

Now in your service you can do like this: Import

import { Observable,of } from 'rxjs';

and then

loginUser(email: string,password: string):Observable<boolean> {
  return of(firebase.auth().signInWithEmailAndPassword(email,password)
    .then(firebase.auth().currentUser.getIdToken()).then(
          (token: string) => {
            this.token = token;
            // Want to return the below return statement
            return true;

          }
        )
    ).catch(
      error => console.log(error)
  ));

Don't change the route from service. Show message and then change route from component