Home > front end >  Angular - display a string property, defined in Child... in the Parent
Angular - display a string property, defined in Child... in the Parent

Time:05-16

If I have a property (a string) that is defined in a child component, how could I display that in a parent component? All the examples I see, seem to involve click events / Event Emmitter. But what if there is no event required?

CodePudding user response:

Talking from Child to Parent

There are a couple of different ways to talk from child to parent to choose from depending on the usecase:

You shouldn't get confused by the 'event'. It is just an event you create in the child as a way to talk to the parent. There doesn't need to be any user triggered event like clicks or anything.

With ViewChild

In parent.component.ts:

export class AppComponent implements AfterViewInit {
  value = 'My Value';

  @ViewChild(SecondChildComponent) someChild!: any

  ngAfterViewInit(): void {
    this.value = this.someChild.someValue
  }

In child.component.ts:

someValue = 'New Value'

This value is only read 'AfterViewInit'. The parent would need some sort of event to update the value when it gets changed in the child component.

With EventEmitter Output

In child.component.ts:

@Output() someEvent = new EventEmitter

someFunction(): void {
  this.someEvent.emit('Some data...')
}

In parent template:

<app-child (someEvent)="handleSomeEvent($event)"></app-child>

In parent.component.ts:

handleSomeEvent(event: any): void {
  // Do something
}

Over a Router Outlet

We can use the onActivate method to get a reference to the component that gets loaded into the router-outlet.

In child.component.ts:


@Output() deleteEvent = new EventEmitter
@Output() addEvent = new EventEmitter

deleteItem(id){
    this.deleteEvent.emit(id)
}
  addItem(data) {
    this.deleteEvent.emit(data)
}

In the parent template:

<router-outlet (activate)="onActivate($event)"></router-outlet>

In parent.component.ts:

onActivate(componentReference) {
   componentReference.deleteEvent.subscribe((id) => {
      // implementation
   });

   componentReference.addEvent.subscribe((data) => {
      // implementation
   })
}

With a Service

We can also use a data service bound to root to share data between unrelated components. This is also useful when a lot of other components need to access the shared data.

In service:

private sharedValue = new BehaviorSubject('')
currentSharedValue = this.sharedValue.asObservable()

changeSharedValue(newValue: string) {
  this.sharedValue.next(newValue)
}

Component changing data:

constructor(
  private dataService: DataService
) { }

changeSharedData(): void {
  this.dataService.changeSharedValue('New Shared Data')
}

Component reading shared data:

value = 'Old Value'
subscription!: Subscription;

constructor(
  private dataService: DataService
) { }

ngOnInit() {
  this.subscription = this.dataService.currentSharedValue.subscribe(newValue => {
    this.value = newValue
  })
}

ngOnDestroy() {
  this.subscription.unsubscribe()
}
  • Related