Reputation: 110
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?
Upvotes: 1
Views: 928
Reputation: 110
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
Upvotes: 1
Reputation:
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');
}
Upvotes: 0