tikonoff
tikonoff

Reputation: 113

Angular sub-component binding doesn't work

I'm trying to display message in sub-component using dependency injection.

Here is first.component.ts:

import { Component } from '@angular/core';
import { SecondComponent } from './second.component';

@Component({
  selector: 'app-first',
  template: `<button (click)="onClick()">Yes</button>
             <app-second></app-second>
             `,
  providers: [ SecondComponent ]
})

export class FirstComponent {
  constructor(private secondComponent: SecondComponent) {}
  onClick() {
    this.secondComponent.Show('Test message');
  }
}

Here is second.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: 'app-second',
  template: '<p>{{ _message }}</p>'
})

export class SecondComponent {
  _message: string;

  Show(message: string) {
    this._message = message;
  }
}

Console show no errors, but {{ _message }} in browser is not updated.

Where am I wrong?

Upvotes: 1

Views: 665

Answers (1)

Joshua Ohana
Joshua Ohana

Reputation: 6131

You can do this one of two ways; expose a public method in your SecondComponent or use @Input as yurzui mentioned

Public method in child component

Change your FirstComponent to

@Component({
  selector: 'app-first',
  template: `<button (click)="onClick()">Yes</button>
             <app-second #second></app-second>
             `,
  providers: [ SecondComponent ]
})

export class FirstComponent {
  @ViewChild('second') second;
  constructor(private secondComponent: SecondComponent) {}
  onClick() {
    second.Show('Test message');
  }
}

and mark the Show method in your SecondComponent as public

or Use @Input to pass data directly to your child component

@Component({
  selector: 'app-first',
  template: `<button (click)="onClick()">Yes</button>
             <app-second message="message"></app-second>
             `,
  providers: [ SecondComponent ]
})

export class FirstComponent {
  public message: string;
  constructor(private secondComponent: SecondComponent) {}
  onClick() {
    this.message = 'Test message';
  }
}

import { Component } from '@angular/core';

@Component({
  selector: 'app-second',
  template: '<p>{{ _message }}</p>'
})

export class SecondComponent {
  @Input() _message: string;
}

Upvotes: 0

Related Questions