AlanObject
AlanObject

Reputation: 9943

Angular Component Input variable not the same as the template

This looks to me like something broken with the Angular framework. Version information below. I have a component that looks like the following -- only the relevant bits are included:

export class RepliesComponent implements OnInit, AfterViewInit {

  @Input() serial: number;

  // ...

  ngOnInit() {
    console.log('RepliesComponent.ngOnInit', this.serial);
  }

  ngAfterViewInit(): void {
    console.log('RepliesComponent.ngAfterViewInit', this.serial);
  }

The template has this:

<h3>Replies Component: {{ serial }}</h3>

The parent template has this:

    <div *ngIf="doc">
      <h3>Replies Here: {{ doc.serial }}</h3>
      <app-replies [serial]="doc.serial"></app-replies>
    </div>

You just can't get more basic than that. But here is what I get:

The parent template renders the expected number and the RepliesComponent template renders the same expected number like this:

Replies Here: 58
Replies Component: 58

Both console.log statements output undefined for the number. And of course all the logic depending on that variable breaks.

RepliesComponent.ngOnInit undefined
RepliesComponent.ngAfterViewInit undefined

So the component state is different from the template's state. Does anyone have any idea of how this could happen, or what I can do to debug it? I have been stuck on this for a day or two and any help appreciated.

% ng version

Angular CLI: 8.3.21
Node: 12.11.0
OS: darwin x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.21
@angular-devkit/build-angular     0.803.21
@angular-devkit/build-optimizer   0.803.21
@angular-devkit/build-webpack     0.803.21
@angular-devkit/core              8.3.14
@angular-devkit/schematics        8.3.21
@angular/cdk                      8.2.3
@angular/cli                      8.3.21
@angular/flex-layout              8.0.0-beta.27
@angular/material                 8.2.3
@bazel/typescript                 0.39.0
@ngtools/webpack                  8.3.14
@schematics/angular               8.3.21
@schematics/update                0.803.21
rxjs                              6.5.4
typescript                        3.5.3
webpack                           4.39.2

Upvotes: 1

Views: 180

Answers (1)

seawave_23
seawave_23

Reputation: 1248

The value of the input variable is used from the time when the component was initalized. To follow the value changes of the input, you will have to use a setter and getter:

@Input('serial') set serial (value: number) {
this._serial = serial
}

get serial(): number{
    return this._serial;
}

or follow the input changes by using the OnChanges hook:

public ngOnChanges(changes: SimpleChanges) {
   if(changes.serial) {
      this._serial = changes.serial.currentValue
   };
}

Upvotes: 1

Related Questions