简体   繁体   中英

Passing value of Observable to variable in Base Component to child component - Angular 5

So I have a base component and in it I have an observable inside its constructor to get a value once it is received inside another component that will validate the user data. However when trying to get this value in the child class the data arrives as undefined. Below the code I'm having problems:

My observable:

@Injectable()
export class ObservableUsuario implements ObservableUtil {
    subject = new Subject<any>();
    setUsuario(variable: any) {
        this.subject.next({ text: variable });
    }

    clearUsuario() {
        this.subject.next();
    }

    getUsuario(): Observable<any> {
        return this.subject.asObservable();
    }

Here observable has set:

 getValue = (refresh: boolean = true) => cacheable(
    () => this.http.get(`${environment.apiEndpoint}/api/Get/Value`, headers()).map(res => {
      this.observableUser.setUsuario(res.json());
      return res.json();
    }),
  );

Base component:

//more code
       perfilLotado: any;
        constructor(
            public observableUser: ObservableUsuario
        ) {
            this.observableUser.getUsuario().subscribe(
                perfil => this.perfilLotado = perfil.text.lotacaoDTO[0].perfilDTO[0].nome);
        }
//more code

Child component:

   export class BaseListComponent extends BaseComponent {

        NgOnInit(){}

        validAction(situacao: number): any {
//Here appearer like undefined...
            console.log(this.perfilLotado);
            if (this.sistema.situacaoRestric[situacao] != undefined) {
                this.showMsg('warn', 'Mensagem de Alerta', this.sistema.situacaoRestric[situacao]);
                return false;
            } else if (this.sistema.situacaoRestric[situacao] == undefined && this.sistema.perfilRestrict[this.perfilLotado] != undefined) {
                this.showMsg('warn', 'Mensagem de Alerta', this.sistema.perfilRestrict[this.perfilLotado]);
                return false;
            } else if (this.sistema.situacaoRestric[situacao] == undefined && this.sistema.perfilRestrict[situacao] == undefined) {
                return true;
            }
        }

In other words, my problem is loading the value that is passed by my observable to a child component class. NOTE: From what I understand it is the last component to load, how can I make it load before the other components of the screen?

Following your description your problem is, that you subscribe to the service and parallely try to fill in data out of the constructor. You're running in some kind of race condition. I tested it myself. If you'd subscribe out of your constructor but call the service's setUsuario()-method out of ngOnInit() this would be sufficient to have your value present when validAction() is called.

This shortened version of your code works, because the subscription happens in the constructor and the "filling" later in ngOnInit():

private perfilLotado: any;

constructor(private observableUsuario: ObservableUsuario) {
    this.observableUsuario.getUsuario().subscribe(
        perfil => {
            this.perfilLotado = perfil;
        });
}

ngOnInit(): void {
    this.observableUsuario.setUsuario('TEST');
}

Yes it is more or less the same, however, that the data was filled well before this part of the code was executed, so I could only catch it after all the code was executed. Then I was able to solve using the BehaviorSubject , setting it together with the other Subject no service. Since I need the two in different points, but as a mistake I will have to leave until I solve the problem.

Follow the code i use in observable:

@Injectable()
export class bObservableUsuario {

  private messageSource = new BehaviorSubject<any>("");
  currentMessage = this.messageSource.asObservable();

  constructor() { }

  changeMessage(obj: any) {
    this.messageSource.next(obj)
  }

Service:

  GetData = (refresh: boolean = true) => cacheable(
    () => this.http.get(`${environment.apiEndpoint}/api/get/data`, headers()).map(res => {
//for now i need two observers here :(..
      this.observableUser.setUsuario(res.json());
//this bObservable solve my problems
      this.bObservable.changeMessage({obj: res.json()});
      return res.json();
    }),

Component child:

@Component({ template: '' })
export class BaseListComponent extends BaseComponent {
    init() {
        this.bObservale.currentMessage.subscribe(d => this.perfilLotado = d.obj);

    }
///more code

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