Ways to trigger child components function from parent component

I am working with a parent-child component setup. In the child component (child.component.ts), there is a method called "childFunction()". Now, I need to call this method from within a function in the parent component. Can you guide me on how to achieve this?

**Parent.html :** 

<div class="box">
    <input type="text" (input)="searchValue=$event.target.value" placeholder={{placeHolder}} />
    
<btn-icon [searchType]='searchType' [searchText]='searchValue'></btn-icon> // child component
</div>

**parent.component.ts :**

export class parentComponent implements OnInit {

parentFunction(){
// **Call** childFunction('inputValue');

}
 
**btn-icon  is Child :**
**btn-icon.component.ts:  (Child)**

export class btn-iconimplements OnInit {
  
  @Input() Type: string;
  @Input() Text: string;

childFunction(inputValue){
      //some logic
    }
}
 

Answer №1

To retrieve the children, simply utilize ViewChild in your code.

export class ParentComponent implements OnInit {

@ViewChild(btn-icon) btnIcon //Make sure to use the class name of your child-component as the argument for ViewChild
  parentFunction(){
     this.btnIcon.childFunction('inputValue');
  }
}

Another method is using a template reference and passing it as an argument to a function:

<div class="box">
    <!--When handling an input event, pass the template reference "child" along with $event.target.value-->
    <input type="text" (input)="change(child,$event.target.value)" placeholder={{placeHolder}} />

    <!--The "#child" is a template reference-->
    <btn-icon #child [searchType]='searchType' [searchText]='searchValue'></btn-icon>
</div>
change(childComponent: BtnIcon, value){
    childComponent.childFunction(value)
}

Answer №2

To easily include the Child Component, utilize the decorator @ViewChild():

@ViewChild(btn-icon)
private btnIcon: btn-icon;

Subsequently, you can interact with its attributes as usual:

this.btnIcon.childFunction();

Answer №3

To access the child component, you can utilize @ViewChild in the parent component:

export class ParentComponent implements OnInit {
   @ViewChild(ChildComponent)    childComponent;
   
   parentFunction(){
     childComponent.childFunction();
   }

The childComponent property will only be populated with the child component after the ngAfterViewInit() lifecycle hook is called.

Note: I have used the class name ChildComponent in camelcase instead of "child-component" as shown in your example.

Answer №4

The callback pattern presents an alternative solution to this issue. To see a functional example, visit stackblitz: https://stackblitz.com/edit/angular-e6hakq

Child component

@Component({
  selector: 'app-child',
  template: `<div>
    <h3>Child var: {{num}}!</h3>
  </div>`,
})
export class ChildComponent implements OnDestroy {
  protected num: number = 0;
  private _param: ParamFn | null = null;

  get param() {
    return this._param;
  }

  @Input() set param(val: ParamFn) {
    this._param = val;
    this._param.registerFn(this.innerComponentFunction);
  }

  private innerComponentFunction = () => {
    this.num++;
  };

  ngOnDestroy() {
    if (this.param) {
      //avoid memory leak
      this.param.deregisterFn();
      this.param.deregisterFn = null;
      this.param.registerFn = null;
    }
  }
}


export type ParamFn =  {
  registerFn: (callback: () => void) => void,
  deregisterFn: () => void
}

Parent component

@Component({
  selector: 'app-parent',
  template: `<app-child 
    [param]="fnParam"></app-child>
    <button (click)="invokeChildFn()">Trigger Child Function</button>
    `,
})
export class ParentComponent {
  private childFn: Function | null = null;

  registerDeactivateChildFunction = (func: () => void) => {
    this.childFn = func;
  };

  deregisterFunction = () => {
    this.childFn = null;
    console.log('deregisterFunction parent');
  };

  protected fnParam: ParamFn = {
    registerFn: this.registerDeactivateChildFunction.bind(this),
    deregisterFn: this.deregisterFunction.bind(this),
  };

  protected invokeChildFn() {
    if (this.childFn) {
      this.childFn();
    }
  }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible for a function within a nodejs module to be defined but display as undefined upon access?

I am currently developing a Discord bot using NodeJS and TypeScript, and I'm facing an issue while trying to import custom modules in a loop with the following code: const eventFiles = fs.readdirSync("./src/events/").filter((file: string) =& ...

Unusual behavior of Typescript with Storybook's addon-docs

I'm trying to integrate storybook addon-docs into my TypeScript React project. Everything seems to be almost working, but I've noticed that the file name is affecting how the props type table gets rendered. Here is my file structure: src - Butto ...

Error in Angular FormArray: Unable to access the 'push' property because it is undefined

Currently, I am working with a form that is divided into 3 subcomponents, each containing 3 form groups. The 3rd group contains a FormArray which will store FormControls representing true/false values for each result retrieved from an API call. Initially, ...

What is the best way to retrieve the input value from a moment object?

Upon receiving a date from the server, I noticed that the time is correct in the _i variable but rounded to 00:00 in the d variable below. How can I access the value in the _i variable? this.xxxxxStartDate = moment( data.xxxxxStartDate ).format("Do M ...

Troubleshooting a TypeScript Problem with React Context

In my AppContext.tsx file, I have defined the following import React, { useState, createContext } from "react"; import { Iitem } from "../utils/interfaces"; interface AppContext { showModal: boolean; setShowModal: React.Dispatch< ...

Tips for effortlessly incorporating a new chip while maintaining a neat arrangement and ensuring button alignment

I am looking to enhance my website by adding chips with new tags in a neatly organized manner. Specifically, I want each new chip to be positioned next to the previous one and have the add-button shift to the right side, always staying in front of the last ...

Experiencing issues while trying to render a component with dynamic content in Next.js

Currently, I am facing an issue while trying to display Leaflet maps in Next.js with Typescript. I came across the suggestion to disable server-side rendering (ssr) to prevent the 'window not defined' error. However, when implementing the followi ...

Is there a method to incorporate lists of varying types in a single v-for loop without causing any issues with type validations?

My current component is designed to display two different datasets, each with their own unique nature of data: state.articleTypeList: string[] state.renderPriceClassNameList: {[key: string]: string[]} To render both datasets within a single v-for componen ...

The type argument '(id: any, title: any, body: any, image: any) => Element' does not match the parameter type

Hello there, I am a beginner in React-Native and I'm facing an issue while trying to map data into View. Despite going through the documentation and other resources, I haven't been able to figure out what mistake I might be making. Can anyone hel ...

Finding parameters in Angular 4

I am working on implementing a multilanguage feature in an Angular app and I need to establish the default language when the site loads. The two languages supported are Spanish and English, with Spanish being the default language. In order to achieve this, ...

Looking for a way to dynamically append a child element within another child

Struggling to include a new child within a specific child in Json myObject:any[] = []; this.myObject = { "type": "object", "properties": { "first_name": { "type": "string" }, "last_name": { "type": "string" }, } } addF ...

Slim API receives a request from Ionic 5

Seeking assistance with making a GET request from my Ionic application to an API constructed using the Slim Framework. Below is the code snippet of the API: <?php header('Access-Control-Allow-Origin: *'); header('Content-Type: applicati ...

The error "Property 'user' does not exist on type 'Session'." occurred while attempting to pass session data using express-session and accessing req.session.user

I'm currently working on creating a basic login form for users to access a website, where I plan to store their session data in a session cookie. The express-session documentation provides the following example for setting it up: app.post('/login ...

Tips on how to properly format a DateTime String

I need help with formatting a DateTime string retrieved from an API where it is in the format of YYYY-MM-DDTHH:MM:SS +08:00 and I want to change it to DD-MM-YY HH:MM getDataFromApi(res) { this.timestamp = this.timestamp.items[0].timestamp; console ...

Sequelize.js: Using the Model.build method will create a new empty object

I am currently working with Sequelize.js (version 4.38.0) in conjunction with Typescript (version 3.0.3). Additionally, I have installed the package @types/sequelize at version 4.27.25. The issue I am facing involves the inability to transpile the followi ...

Guide to setting up a trigger/alert to activate every 5 minutes using Angular

limitExceed(params: any) { params.forEach((data: any) => { if (data.humidity === 100) { this.createNotification('warning', data.sensor, false); } else if (data.humidity >= 67 && data.humidity <= 99.99) { ...

What does the error message "JSON.parse: unexpected character at line 1 column 1 of the

In the process of developing a node.js module that involves importing a JSON file: const distDirPath = "c:/temp/dist/"; const targetPagePath = "c:/temp/index.html"; const cliJsonPath = "C:/CODE/MyApp/.angular-cli.json"; const fs = require('fs'); ...

Converting and Casting Enums in TypeScript

Is there a way to convert one enum into another when they have the same values? enum Enum1 { Value = 'example' } enum Enum2 { Value = 'example' } const value = Enum1.Value const value2 = value as Enum2 ...

The parameter 'host: string | undefined; user: string | undefined' does not match the expected type 'string | ConnectionConfig' and cannot be assigned

My attempt to establish a connection to an AWS MySQL database looks like this: const config = { host: process.env.RDS_HOSTNAME, user: process.env.RDS_USERNAME, password: process.env.RDS_PASSWORD, port: 3306, database: process.env.RDS_DB_NAME, } ...

Unlock the power of asynchronous dependencies on a global scale with Inversify

I'm looking to resolve an asynchronous dependency at the top level without relying on top-level awaits. Currently, I've implemented a temporary solution by defining an asynchronous function getService() in the controller file. However, this appr ...