1

I have a problem with @input(), two out of three input have an undefined value when I want to use it but can be display using interpolation in the template file.

.ts :

export class NoteCanvasPageComponent {
  @Input() note: any;
  @Input() canvasWidth: any;
  @Input() canvasHeight: any;

  @ViewChild("TextArea") textArea: any;

  constructor() {

  }

  ngAfterViewInit(){
    console.log(this.note.posY + " " + this.canvasHeight);
    console.log(this.note.posX + " " + this.canvasWidth);
    this.textArea.nativeElement.style.top = this.note.posY * this.canvasHeight;
    this.textArea.nativeElement.style.left = this.note.posX * this.canvasWidth;
  }

}

console.log() print this :
0.623 undefined 0.578 undefined

template file :

<textarea #TextArea class="note-canvas-page">
  {{note.text}}
  {{canvasHeight}}
  {{canvasWidth}}
</textarea>

Give :
This is a note 512 360

Why only two out of three input have undefined value in the component file ?

I use the component like this :

<div *ngFor="let note of arrayNotes">
  <note-canvas-page [canvasHeight]=canvasHeight [canvasWidth]=canvasWidth [note]=note *ngIf="note.display"></note-canvas-page>
</div>

Thank you for your help

4
  • Are you sure that canvasHeight and canvasWidth is already set when assigning to note-canvas-page? Commented Jul 10, 2018 at 10:21
  • where you are initializing the variable canvasHeight and canvaswidth?? Commented Jul 10, 2018 at 10:32
  • @mvermand Yes I think, I use this variable in the parent component and the value can be display using {{canvasHeight}} in note-canvas-page Commented Jul 10, 2018 at 11:09
  • You're missing the "" around canvasHeight, canvasWidth , note Commented Jul 10, 2018 at 11:48

3 Answers 3

2

Another solution might be:

export class NoteCanvasPageComponent {
  _canvasWidth: any;
  _canvasHeight: any;
  _note: any;

  @Input() 
  set note(value: any) {
      this._note = value;
      initComponent();
  }

  get note() {
      return this._note;
  }

  @Input() 
  set canvasWidth(value: any) {
      this._canvasWidth = value;
      initComponent();
  }

  get canvasWidth() {
      return this._canvasWidth ;
  }

  @Input() 
  set canvasHeight(value : any) {
      this._canvasHeight = value;
      initComponent();
  }

  get canvasHeight() {
      return this._canvasHeight ;
  }

  @ViewChild("TextArea") textArea: any;

  constructor() {

  }

  ngAfterViewInit(){

  }

  initComponent() {
    if(this._note && this._canvasWidth && this._canvasHeight) {
        console.log(this._note.posY + " " + this._canvasHeight);
        console.log(this._note.posX + " " + this._canvasWidth);
        this.textArea.nativeElement.style.top = this._note.posY * this.canvasHeight;
        this.textArea.nativeElement.style.left = this._note.posX * this._canvasWidth;
    }
  }

}

This has the added value that style.top and style.left will be recalculated whenever note, canvasHeight or canvasWidth changes.

Sign up to request clarification or add additional context in comments.

Comments

1

Can you change your code to the following:

export class NoteCanvasPageComponent {
  _canvasWidth: any;

  @Input() note: any;

  @Input() 
  set canvasWidth(value: any) {
      debugger;                     // <-- breakpoint 1
      this._canvasWidth = value;
  }

  @Input() canvasHeight: any;

  @ViewChild("TextArea") textArea: any;

  constructor() {

  }

  ngAfterViewInit(){
    debugger;          // <-- breakpoint 2
    console.log(this.note.posY + " " + this.canvasHeight);
    console.log(this.note.posX + " " + this._canvasWidth);
    this.textArea.nativeElement.style.top = this.note.posY * this.canvasHeight;
    this.textArea.nativeElement.style.left = this.note.posX * this._canvasWidth;
  }

}

This code will break in two places. See if it reaches breakpoint 1 before breakpoint 2 and see what the value is in breakpoint 1.

4 Comments

Debbuger said that the value is undefined so you're right, the input isn't already set when assigning to note-canvas-page. But I still don't understand why {{canvasHeight}} works
Then look at my second answer, that might fix your issue. It will recalculate whenever something changes to your inputs, even after ngInit or ngAfetrViewInit
{{canvasHeight}} works because the input is set after the ngAfterViewInit is already executed. Any change at any moment to your input will be reflected in {{canvasHeight}}, but the ngAfterViewInit is only executed once. If the canvasHeight is not yet set at that moment, calculation will not be as desired
Yes, it works with some change ! Thank you very much for the solution and the explanations :)
-1

Try to replace this:

 <div *ngFor="let note of arrayNotes">
      <note-canvas-page [canvasHeight]=canvasHeight [canvasWidth]=canvasWidth [note]=note *ngIf="note.display"></note-canvas-page>
    </div>

with:

    <div *ngFor="let note of arrayNotes">
      <note-canvas-page [canvasHeight]=note.canvasHeight [canvasWidth]=note.canvasWidth [note]=note *ngIf="note.display"></note-canvas-page>
    </div>

1 Comment

canvasHeight and Width aren't attribute of note object.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.