0

I have a problem with this one.

I have a create a timeline to display schedule when vessels are supposed to dock on different terminals. it looks like that:

<ul class="vessels-schedule">
  <li *ngFor="let terminal of terminals" class="mt-3">
    <div class="terminal-schedule" #terminalSchedule #test>
      <div class="terminal-information" #terminalInformation>
        <h3 class="terminal-name">{{terminal.name}}</h3>          
      </div>
      <div *ngFor="let date of dates" class="vessel-date" #vesselDate></div>
      <div class="vessels">
        <div *ngFor="let vessel of terminal.vessels; let index = index"
            class="vessel" 
            [style.left.px]="getVesselPosition(vessel.estimateTimeArrival)"
            tabindex="0" #vessel>
        ...

It renders a row by terminal + a grid for each day *ngFor="let date of dates" and all vessels for this terminal positioned at the right date/time.

I have also a couples of ViewChild to dynamically calculate position:

@ViewChildren('terminalSchedule') terminalSchedule: QueryList<ElementRef>;
@ViewChild('terminalInformation') terminalInformation: ElementRef;
@ViewChild('vesselDate') vesselDate: ElementRef;
@ViewChild('vessel') vessel: ElementRef;

...

ngAfterViewInit(): void {
  this.terminalSchedule.changes.subscribe(item => {
    if (this.terminalSchedule.length) {
      this.terminalScheduleOffsetWidth = this.terminalSchedule.first.nativeElement.offsetWidth;
      this.terminalInformationOffsetWidth = this.terminalInformation.nativeElement.offsetWidth;
      this.vesselDateOffsetWidth = this.vesselDate.nativeElement.offsetWidth;
      this.vesselOffsetWidth = this.vessel !== undefined ? this.vessel.nativeElement.offsetWidth : 0;
      ...

And a function to set the position that returns a pixel value.

I don't know if it's because I don't initialize it at the right place, but when I bind data I have this in the console (it works though!):

NG0100: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value for 'left': '0'. Current value: '301.5416666666667'.

I initialize the terminal list right in OnChanges():

ngOnChanges(): void {
  ...
  this.getTerminal();
}

Also, in the complementary question, I try to figure the best approach for resizing. Right now, I change a boolean property on resize to force re-render, I don't know if it's a good idea...

usalin
  • 141
  • 1
  • 7
Jonathan Anctil
  • 1,025
  • 3
  • 20
  • 44

1 Answers1

0

Try to use ChangeDetectorRef with the method detectChanges() in your ngAfterViewInit().

constructor (private cd: ChangeDetectorRef) { ... }

...

ngAfterViewInit(): void {
   this.cd.detectChanges();
   ... the rest of your method
}
archelite
  • 174
  • 1
  • 12
  • https://stackoverflow.com/questions/34364880/expression-has-changed-after-it-was-checked if I call detectChanges() in ngAfterContentChecked, it fix my problem. – Jonathan Anctil Jul 12 '21 at 15:49