aman
aman

Reputation: 6262

Angular: Getting data from child without event

Using Angular 6 here. I have a page which has about 2 child components. The first one has 2 input text and the second one has one dropdown. My parent component just has the button click.

I know I can use Eventemitter on my child component and pass the value to my parent but how shall I pass the value from my child if there are no button click events. I tried to user ViewChild which sort of works but there is a delay until the view is fully loaded. I am using ViewChild as below:

--Parent--

import { Component, ViewChild, AfterViewInit } from '@angular/core';
import { ChildComponent } from "../child/child.component";

@Component({
  selector: 'app-parent',
  template: `
    Message: {{ message }}
    <app-child></app-child>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent implements AfterViewInit {

  @ViewChild(ChildComponent) child;

  constructor() { }

  message:string;

  ngAfterViewInit() {
    this.message = this.child.message
  }
}

--Child--

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

@Component({
  selector: 'app-child',
  template: `
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent {

  message = 'Hola Mundo!';

  constructor() { }

}

I have taken the above ex from https://angularfirebase.com/lessons/sharing-data-between-angular-components-four-methods/

Could anyone provide inputs how I can achieve passing/reading data from child without having to use any button click/emitter.

--Updated--

--Child--

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

@Component({
  selector: 'ct-child',
  templateUrl: './child.html'
})
export class ChildComponent implements OnInit {
  childmessage: string = "Child Message!"
  constructor() { }

  ngOnInit() {}
}

--Parent--

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

@Component({
  selector: 'ct-parent',
  templateUrl: './parent.html'
})
export class ParentComponent implements OnInit  {

  constructor() { }

    message: string;

  getDataFromChild(child1): void {
    this.message = child1.message;    
  } 


  ngOnInit() {}  
}

--Parent Html--

 Message: {{message}}
 <ct-child #child1></ct-metadata>
 <button type="button" (click)="getDataFromChild(child1)">Click Me!</button>

I have tried above as per comments but this does not work.

Upvotes: 6

Views: 10098

Answers (3)

emkay
emkay

Reputation: 807

From what I understood after reading your post and comments below, you have a structure as follows in your parent.component.html

 <app-child1></app-child1>
 <app-child2></app-child2>
 <button type="button">Click Me!</button>

When you click on the button, you want to get the data from child1 and child2 into the parent component.

So one way to solve this is using template reference variable,

<app-child1 #child1></app-child1>
<app-chidl2 #child2></app-child2>
<button type="button" (click)="getDataFromChild(child1,child2)">Click Me!</button>

Inside your parent typescript

getDataFromChild(child1,child2) {
  dataFromChild1 = child1.getData();
  dataFromChild2 = child2.getData();
}

Add getData() method in both the child1 and child2 component's ts and return the required data.

Upvotes: 4

ABOS
ABOS

Reputation: 3823

If you just want to pass some data as shown in your example, you can do like this

 Message: {{ child.message }}
 <app-child #child></app-child>

Upvotes: 3

Anjil Dhamala
Anjil Dhamala

Reputation: 1622

You talk to your child via @Input() and talk back to parent with @Output.

For your example, you get back the message from child using an @Output.

Here's your child component.

import { Component} from '@angular/core';
@Component({
  selector: 'app-child',
  template: `
  `,
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements AfterViewInit {
  @Output() messageChanged: EventEmitter<string>();
  message = 'Hola Mundo!';

  constructor() { 
     this.messageChanged = new EventEmitter<string>();
  }

  ngAfterViewInit() {
    this.messageChanged.next(this.message);
  }
}

This is how your parent needs to look.

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

@Component({
  selector: 'app-parent',
  template: `
    Message: {{ message }}
    <app-child (messageChanged)="onMessageChange($event)"></app-child>
  `,
  styleUrls: ['./parent.component.css']
})
export class ParentComponent {
  constructor() { }

  message:string;

  onMessageChange(message: string) {
    this.message = message;
  }
}

Upvotes: -1

Related Questions