Я новичок в Angular и использую Angular 7. У меня есть переменная userEmail со значением по умолчанию "unknown" в общей службе pagedoctorService. После успешного входа в систему переменная обновляется со входом в Email. Я импортировал этот сервис в другие компоненты, но при доступе к userEmail из других компонентов он показывает значение по умолчанию (неизвестно).

Вот что я сделал:

< Сильный > app.module.ts

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

< Сильный > pagedoctor.service.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
    });
  }
...

< Сильный > login.component.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');
}

< Сильный > urlform.component.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*

Похоже, я работаю с новой версией сервиса, пока я предоставляю его на уровне модуля. Я не совсем уверен, что мне здесь не хватает. Заранее благодарим за сотрудничество.

1
Reza Saberi 2 Май 2019 в 10:35

3 ответа

Лучший ответ

Лучший способ предоставления экземпляра службы в корневом инжекторе и, следовательно, всего приложения:

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

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

См. https://angular.io/guide/providers.

Пример здесь: https://stackblitz.com/edit/angular-fumwxh

Важный

Попробуйте оставить свой конструктор чистым. Делать только задания, никаких действий. Не вызывайте никаких методов в конструкторе. Не могли бы вы вызвать метод init извне, а не внутри вашего конструктора. Может быть, проблема в асинхронном методе init?

Но ваш код также должен работать. Может быть, вы можете предоставить код вашего PagedoctorService.

ОБНОВЛЕНИЕ Ааа перенаправление. Хорошо, это решает проблему! В вашем login.component вы звоните: this.signIn.loginRedirect ('/ urlform').

При перенаправлении SPA будет перезагружен и весь инжектор создан с нуля. Это означает, что все ваше состояние потеряно. Вы можете избежать этого, например, используя localalstorage или sessionstorage!

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);
  }
}
...
1
Pierre 2 Май 2019 в 08:49

Я был бы осторожен с размещением публичных объектов в сфере услуг. Единственные общедоступные свойства, которые я обычно добавляю в сервисы, это субъекты управления состоянием. Если вы хотите передать userEmail другим компонентам, я бы предложил либо установить его в локальном хранилище, поместив его в предмет, который обновляется при его изменении, либо в качестве ввода от родителя к потомку. Для маршрутизации вы также можете передавать данные из компонента входа в систему по маршруту навигации через конфигурации маршрута. Пожалуйста, смотрите ссылку ниже:

Как передать данные в Angular-маршрутизируемые компоненты?

Надеюсь, это поможет.

1
Paul 2 Май 2019 в 08:53

Попробуйте это в login.component

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

В PagedoctorService

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

Конец в urlform.component.ts

  this.pdService.emailActtual.subscribe(res => console.log(res)); 
0
PuntanetDeveloper 2 Май 2019 в 07:45