简体   繁体   中英

Angular 5. How to update data from service in component?

I have a login service and component, which both work with firebase, and its doesn't matter, just explains what's going on.

So ! I have component with login/signIn form, which works well with auth.service.ts . And I have another component user-data.component.js , which always shown on the top of a page. I want to get user information every time user object changes in auth.service.ts (by switching accounts in auth.component.ts ) to show user image.

It's hard to explain, but I hope someone can explain me how to resolve this task. Thank you !

auth.service.ts

import {
  Injectable
} from '@angular/core';

import {
  AngularFireAuth
} from 'angularfire2/auth';
import * as firebase from 'firebase/app';

import {
  Observable
} from 'rxjs/Observable';

@Injectable()
export class AuthService {
  user: Observable < firebase.User > ;

  constructor(private firebaseAuth: AngularFireAuth) {
    this.user = firebaseAuth.authState;
  }

  signup(email: string, password: string) {
    this.firebaseAuth
      .auth
      .createUserWithEmailAndPassword(email, password)
      .then(value => {
        console.log('Success!', value);
      })
      .catch(err => {
        console.log('Something went wrong:', err.message);
      });
  }

  login(email: string, password: string) {
    this.firebaseAuth
      .auth
      .signInWithEmailAndPassword(email, password)
      .then(value => {
        console.log('Nice, it worked!', value);
      })
      .catch(err => {
        console.log('Something went wrong:', err.message);
        alert('No user with current data')
      });
  }

  logout() {
    this.firebaseAuth
      .auth
      .signOut();
  }

}

user-data.component.js (here i tried to update user...)

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../shared/services/auth/auth.service';
import { AngularFireAuth } from 'angularfire2/auth';

@Component({
  selector: 'app-user-data',
  templateUrl: './user-data.component.html',
  styleUrls: ['./user-data.component.css']
})
export class UserDataComponent implements OnInit {

  photoUrl;

  ngOnInit() {
      this.authService.user.subscribe(user => {
        this.photoUrl = user.photoURL;
      });
      this.afAuth.authState.subscribe(user => {
        this.photoUrl = user.photoURL;
      });
  }

  constructor(public authService: AuthService, public afAuth: AngularFireAuth) {

  }

}

and auth.component.ts (I don't know if it's really needed, but)

import { Component } from '@angular/core';
import { AuthService } from '../shared/services/auth/auth.service';
import { AngularFireAuth } from 'angularfire2/auth';
import * as firebase from 'firebase/app';

@Component({
  selector: 'app-auth',
  templateUrl: './auth.component.html',
  styleUrls: ['./auth.component.css']
})
export class AuthComponent  {

  currentUser;

  constructor(public afAuth: AngularFireAuth, public authService: AuthService) {
  }

  googleLogin() {
    this.afAuth.auth.signInWithPopup(new firebase.auth.GoogleAuthProvider());
    this.afAuth.authState.subscribe(user => {
      this.currentUser = user;
    });
  }

  // FireBase login
  email: string;
  password: string;


  signup() {
    this.authService.signup(this.email, this.password);
    this.email = this.password = '';
    this.authService.user.subscribe(user => this.currentUser = user);
    console.log(this.currentUser);
  }

  login() {
    this.authService.login(this.email, this.password);
    this.email = this.password = '';
    this.authService.user.subscribe(user => this.currentUser = user);
    console.log(this.currentUser);

  }

  logout() {
    this.authService.logout();
  }

}

Observable provide support for passing messages between publishers and subscribers in your application. Following are the code snippets:

auth.service.ts

/*getUserInfo function for publishing values between components
*/
private userInfoSource = new Subject<string>();
userInfo$ = this.userInfoSource.asObservable();

getUserInfo(info: string) {
   this.userInfoSource.next(info);
}

auth.component.ts

/* Pass user information every time when user object changes
*/
this.authService.getUserInfo(info);

user-data.component.ts

import {Subscription} from 'rxjs/Subscription';
...
subscription: Subscription
...
constructor(private authService: AuthService,..) {
   /*subscribing userInfo$ observable to consume values. 
     It start listening when getUserInfo is trigger in auth.component.ts
   */
    this.subscription = authService.userInfo$.subscribe(
      info => {
        console.log(info);
    });
  }
ngOnDestroy() {
    // Unsubscribe an observable to prevent memory leak when component destroyed
    this.subscription.unsubscribe();
  }

Ref: https://angular.io/guide/observables | https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM