1
votes

partager le service sur l'ensemble des composants dans Angular

Je suis nouveau sur Angular et j'utilise angular 7. J'ai une variable userEmail avec la valeur par défaut "unknown" dans un service partagé pagedoctorService . Après une connexion réussie, la variable est mise à jour avec l'e-mail connecté. J'ai importé ce service dans d'autres composants mais en accédant à userEmail à partir d'autres composants, il affiche la valeur par défaut (inconnue).

Voici ce que j'ai fait:

app.module.ts

import { Component, OnInit, Input } from '@angular/core';
import { PagedoctorService } from '../../services/pagedoctor.service';
...
...
constructor(private pdService: PagedoctorService) {
console.log(this.pdService.userEmail); // <== This shows *unknown*

pagedoctor.service.ts

import { Component, OnInit } from '@angular/core';
import { Router, NavigationStart} from '@angular/router';
import { PagedoctorService } from '../../services/pagedoctor.service';
...
constructor(private pdService: PagedoctorService){}
ngOnInit() {
...
//After successful login attempt using Okta
this.pdService.userEmail = res.user.profile.login; 
console.log(this.pdService.userEmail); //This shows that email is set correctly
this.signIn.loginRedirect('/urlform');
}
login.component.ts
import { Injectable } from '@angular/core';
import { OktaAuthService } from '@okta/okta-angular';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class PagedoctorService {

  private accessToken;
  private headers;

  public userFullname: string= 'unknown';
  public userEmail: string= 'unknown';

  constructor(private oktaAuth: OktaAuthService, private http: HttpClient) {
    this.init();
  }

  async init() {
    this.accessToken = await this.oktaAuth.getAccessToken();
    this.headers = new HttpHeaders({
      Authorization: 'Bearer ' + this.accessToken
    });
  }
...

urlform.component.ts

...
import { PagedoctorService } from './services/pagedoctor.service';
...
...
providers: [PagedoctorService],
...


2 commentaires

pourriez-vous s'il vous plaît fournir le code du PagedoctorService?


@BernardPagoaga mis à jour avec le code de service en bref


3 Réponses :


1
votes

La meilleure façon de fournir une instance de service dans l'injecteur racine et donc dans toute votre application est:

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

@Injectable({
  providedIn: 'root',
})
export class PagedoctorService {
...
public get userFullname(): string {
    const res = localStorage.getItem('userFullname');
    return res == undefined ? 'unknown' : res;
  }
  public set userFullname(value: string) {
    localStorage.setItem('userFullname', value);
  }
}
...

Voir: https://angular.io/guide/providers

Un exemple ici: https://stackblitz.com/edit/angular-fumwxh

Important

Essayez de nettoyer votre constructeur. Ne faites que des affectations, aucune action. N'appelez aucune méthode dans un constructeur. Pourriez-vous s'il vous plaît appeler la méthode init de l'extérieur et non de l'intérieur de votre constructeur. Peut-être que la méthode async "init" est le problème.

Mais votre code devrait également fonctionner. Peut-être que vous pouvez fournir le code de votre PagedoctorService.

MISE À JOUR Ahh redirection. Ok cela résout le problème! Dans votre login.component, vous appelez: this.signIn.loginRedirect ('/ urlform').

Lorsque vous redirigez, le SPA sera rechargé et tout l'injecteur est créé à partir de zéro. Cela signifie que tout votre état est perdu. Vous pouvez éviter cela en utilisant localstorage ou sessionstorage par exemple!

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

@Injectable({
  providedIn: 'root',
})
export class PagedoctorService {
}


6 commentaires

Bonjour, voici un exemple que j'ai fait: stackblitz.com/edit/angular-fumwxh . Ça marche. pouvez-vous s'il vous plaît vous assurer que vous n'avez pas ajouté le fournisseur dans le fournisseur de composants?


Oui j'ai vérifié et je n'ai pas de services fournis dans aucun composant!


Pourriez-vous fournir plus de code? Je ne vois pas l'erreur dans le code ci-dessus.


à partir de quel fichier voulez-vous en savoir plus?


Pourriez-vous s'il vous plaît appeler la méthode init de l'extérieur et non de l'intérieur de votre constructeur. Peut-être que le methid async est le problème.


Continuons cette discussion dans le chat .



0
votes

essayez ceci dans login.component

  this.pdService.emailActtual.subscribe(res => console.log(res)); 

dans PagedoctorService

` private emailOriginale = new BehaviorSubject('unknown');
     emailActtual = this.emailOriginale .asObservable(); 
     changeEmail(email: string) {
         this.emailOriginale.next(email)
     }`

se terminer par urlform.component.ts

this.pdService.changeEmail(res.user.profile.login);


0 commentaires

1
votes

Je ferais attention à ne pas mettre les propriétés publiques dans les services. Les seules propriétés publiques que j'ajoute habituellement aux services sont des sujets pour gérer l'état. Si vous souhaitez transmettre userEmail à d'autres composants, je suggérerais de le configurer dans le stockage local, en le mettant en tant que sujet mis à jour lorsque vous le modifiez ou en tant qu'entrée du parent à l'enfant. Pour le routage, vous pouvez également transmettre les données du composant de connexion à l'itinéraire parcouru via les configurations d'itinéraire. Veuillez consulter le lien ci-dessous:

Comment puis-je transmettre des données aux composants routés Angular? < / a>

J'espère que cela vous aidera.


0 commentaires