I have one parent and 2 child components like below
Parent-component.html
<child-component-1 [id]="id"></child-component-1>
<child-component-2></child-component-2>
child-component-1 has ngb-carousel component to show warnings and alerts to user.And this component is being created due to id and its result comes from API like below
child-component-1.ts
alertFound;
this.service.checkAlert(id).subscribe((result:any)=>{
if(result.alertFound){
this.alertFound=true;
}
})
child-component-1.html
<ngb-carousel #carousel *ngIf="alertFound" class="carousel-alert" [interval]="false" [wrap]="false"
[showNavigationIndicators]="false">
........................(Things go on here after result comes)
</ngb-carousel>
In child-component-2,I need to get the height of this ngb-alert to make dynamic height calculation on the screen.If it exists,I need to subtract it from window.innerheight.
child-component-2.html
<div [style.height.px]="actualHeight"></div>
child-component-2.ts
this.actualHeight = window.innerHeight - 269;
Interestingly on child-component-1 when I tried to track it like below
@ViewChild('carousel', {read: ElementRef, static:false}) elementView: ElementRef;
ngAfterViewInit(){
console.log(this.elementView.nativeElement.offSetHeight);
//throws height of created carousel first,then if next id doesnt have alert still shows me the height which previously created
}
it shows previously created carousel height even though result is false and carousel couldn't be created at that moment.I guess this happening because result sometimes arrives very late,sometimes fast.To listen detections on viewchild I found something like below which works exactly as I wanted and solved emitting non-created alert height problem
@ViewChildren('carousel', {read: ViewContainerRef}) viewContainerRefs;
ngAfterViewInit() {
this.viewContainerRefs.changes.subscribe(item => {
if (item) {
console.log(item._results[0]._lContainer[0][0].offsetHeight);
}
})
}
Now problem is sending this height to child-component-2 where I should calculate height dynamically.
I considered 2 options.First one is creating subject on a service,emitting height to it from child-component-1 and listening it on child-component-2 like below
service.ts
alertActive = new BehaviorSubject(0);
setAlertHeight(value:number){
this.alertActive.next(value)
}
child-component-1
ngAfterViewInit() {
this.viewContainerRefs.changes.subscribe(item => {
if (item) {
this.service.setAlertHeight(item._results[0]._lContainer[0][0].offsetHeight);
}
})
}
child-component-2
this.alertActive.subscribe(value=>{
if(value){
this.actualHeight-=value;
}
})
On the example above,it causes the problem to bring height,even though alert not created.I logged subscribes on console from child-2 and child-1 and noticed that child-2 prints to console even though child1 didnt emit anything to it.
So I considered another option to send height from child-1 to parent via @Output and then via Input to child2 like below
child-1
@Output() transferHeight: EventEmitter<any> = new EventEmitter();
this.viewContainerRefs.changes.subscribe(item => {
if (item) {
this.transferHeight.emit(item._results[0]._lContainer[0][0].offsetHeight);
}
})
parent
<child-component-1 (transferHeight)="transferedHeight($event)" [id]="id"></child-component-1>
<child-component-2 [transferredHeight]="transferredHeight"></child-component-2>
alertHeight;
transferedHeight(comingHeight){
this.alertHeight=comingHeight;
}
child-2
@Input() transferredHeight;
ngOnInit(){
this.actualHeight-=this.transferredHeight;
}
this one really handles the problem that I mentioned previously.But if carousel created after child-2 created due to late network resut ,it returns undefined.Therefore I tried to use ngOnChanges to listen changes on the Input variable like below
ngOnChanges(changes: SimpleChanges) {
console.log(changes.transferredHeight.currentValue)
}
this console.log doesnt print anything although I implemented onChanges.So Im waiting for your help.If there's a way to listen viewContainerRefs.changes of child-1 from child-2 would be the best case