Changing properties of a parent component from a child component in Angular 2

Currently, I am utilizing the @input feature to obtain a property from the parent component. This property is used to activate a CSS class within one of the child components.

Although I am successful in receiving the property and activating the class initially, it seems to work only once. The property received from the parent is of boolean data type. When I attempt to change this status to false from the child component, it does not reflect back in the parent component.

To see the code in action, you can check out this Plunkr: https://plnkr.co/edit/58xuZ1uzvToPhPtOING2?p=preview

app.ts

import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { HeaderComponent } from './header';
import { SearchComponent } from './header/search';

@Component({
  selector: 'my-app',
  template: `
    <app-header></app-header>
  `,
})
export class App {
  name:string;
  constructor() {
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, HeaderComponent, SearchComponent ],
  bootstrap: [ App ]
})
export class AppModule {}

header.ts

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

@Component({
  selector: 'app-header',
  template: `<header>
              <app-search [getSearchStatus]="isSearchActive"></app-search>
              <button (click)="handleSearch()">Open Search</button>
            </header>`
})
export class HeaderComponent implements OnInit {
  isSearchActive = false;

  handleSearch() {
    this.isSearchActive = true
    console.log(this.isSearchActive)
  }

  constructor() { }
  ngOnInit() { }
}

header/search.ts

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

@Component({
  selector: 'app-search',
  template: `<div id="search" [class.toggled]="getSearchStatus">
              search 
              <button  (click)="getSearchStatus = false" class="close">Close Search</button>
            </div>`
})
export class SearchComponent implements OnInit {
  @Input() getSearchStatus: boolean;

  constructor() { }

  ngOnInit() {

  }
}

While examining the provided plunker, you'll notice that the open search function stops working after the first usage. Following the closure of the search, attempting to trigger it again proves to be ineffective.

My query pertains to whether using @input is fitting for this particular scenario. Any assistance in rectifying this issue would be greatly appreciated. (Please update the Plunker with solutions.)

Answer №1

To achieve two-way data binding, you must utilize a specific technique.

@Input() only facilitates one-way data binding. To establish two-way data binding, you must include an @Output() that corresponds to the property and appends "Change" as a suffix.

@Input() getStatus: boolean;
@Output() statusChange = new EventEmitter<boolean>();

Whenever you need to inform the parent component about changes made to your property, you should use the following notification:

this.statusChange.emit(updatedValue)

In the parent component, you have to use the banana-in-a-box notation for that particular property:

[(getStatus)]="myBoundProperty"

Additionally, you can bind to the property and trigger a callback function in the child component when it undergoes a change:

[getStatus]="myBoundProperty" (statusChange)="myCustomCallback($event)"

For more details, refer to this example on Plunker.

Answer №2

Here's another technique: utilize rxjs/BehaviorSubject to communicate status changes between different components.
Take a look at the example.
I labeled the subject with a 'Rxx' suffix, so the BehaviorSubject for searchStatus will be known as searchStatusRxx.

  1. Initialize it in the parent component like
    searchStatusRxx = new BehaviorSubject(false);
  2. Pass it to the child component using @Input
  3. In the child template, use the async pipe.
  4. In both the parent and child components, call searchStatusRxx.next(value) to update the value.

Answer №4

Here is another alternative method. Check out this Plunkr. The goal is to have a single source of truth, which we can achieve by placing it inside the child component.

  • Initialize searchStatus in the child component: searchStatus = false
  • In the parent template, access the child component instance with #as or any desired name.
  • Modify the searchStatus variable in the parent component using #as.searchStatus, and in the child component using this.searchStatus.

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

Enabling Angular Elements to handle non-string properties and inputs

When working with Angular Elements, inputs can be supplied through HTML attributes like so: <some-custom-element someArg="test value"><some-custom-element> An alternative method is utilizing setAttribute. However, it's important to note ...

Using Angular Ionic for a click event that is triggered by a specific class

I am utilizing Highcharts and would like to click on the legend upon loading. With the use of Angular Ionic, how can I trigger a click on the .highcharts-legend-item class within the ngOnInit() {} method? I am aiming to click on this class as soon as the ...

Tips for managing variables to display or hide in various components using Angular

In this example, there are 3 main components: The first component is A.component.ts: This is the parent component where an HTTP call is made to retrieve a response. const res = this.http.post("https://api.com/abcde", { test: true, }); res.subscribe((r ...

Struggling with incorporating GlobalStyles in the app.tsx file

I have been working with next13 and styled-components. Initially, everything seemed fine in my file globalStyles.ts, and all was functioning perfectly. However, I started encountering errors related to the import of <GlobalStyles/>. Specifically, th ...

PrimeNG's Angular component pTree TreeNode

Is there a way in Angular to retrieve the positions of nodes within a TreeNode hierarchy based on their display order? I have data structured as TreeNode objects, which include children that can branch off further. How can I access these nodes according t ...

Encountering an issue with a custom hook causing an error stating "Attempting to access block-scoped variable 'X' before its declaration."

Currently, I am in the process of developing my initial custom hook. My confusion lies in the fact that an error is being displayed, even though the function is defined just a few lines above where it's invoked. Here is the relevant code snippet: f ...

Using Angular 2's ngModel directive to bind a value passed in from an

Using [(ngModel)] in my child component with a string passed from the parent via @Input() is causing some issues. Although the string is successfully passed from the parent to the child, any changes made to it within the child component do not reflect bac ...

Issue with Jest/SuperTest Express integration tests: encountering "Can't set headers after they are sent" error when making requests to the same endpoint in multiple test cases

Dealing with a tricky situation here.. I'm currently in the process of writing integration tests for an Express (Typescript) app, using Jest and Supertest. My challenge lies in having multiple tests for the same endpoint, specifically to test respon ...

Tips for customizing Material UI's styled() SVG icon to accept SVG icon as a react component:

Currently, I have functioning code that uses the "any" type for props. When transitioning to MUI v5 and using the mui v4 makeStyles, this approach raises compatibility issues that were not present before. // Import SVG Icons components import { ReactCo ...

VS Code failing to detect Angular, inundated with errors despite successful compilation

Having some issues with loading my angular project in vscode. It used to work fine, but suddenly I'm getting errors throughout the project. I have all the necessary extensions and Angular installed. https://i.stack.imgur.com/qQqso.png Tried troubles ...

Sending a JSON payload from Angular to C# can result in a value of 0 or null being received

As a beginner working on my Angular&C# project, I encountered an issue. Despite sending a JSON from Angular to C# (POST) with values, the C# side is not receiving anything (value 0 for int and null for string). I can't figure out what I'm doi ...

How to configure mat-sort-header in Angular Material for mat-table

My current table is created using Angular Material: <mat-table *ngIf="!waiting" class="table-general table-summary" #table [dataSource]="dataSource" matSort> <mat-header-row class="header_row" *matHeaderRowDef="headerKeys"></mat-header ...

How to incorporate a popup modal in your project and where should you place the DialogService constructor

Currently, I am in the process of developing a CRUD ASP.NET Core application using Angular 2 and Typescript. Prior to incorporating a popup feature, this was my output: https://i.stack.imgur.com/vHvCC.png My current task involves placing the "Insert or e ...

What is the process for incorporating the jsnetworkx library into an ionic or angular 4 project?

When using any Ionic3 app service import * as jsnx from 'jsnetworkx'; The output error message is: Uncaught (in promise): Error: Cannot find module "lodash/lang/isPlainObject" Error: Cannot find module "lodash/lang/isPlainObject" at webpackMis ...

Can Angular Interpolation be utilized to showcase Angular components?

I am currently working with an Angular component that relies on a getData method to display results using Angular interpolation in its template. However, I have encountered a scenario where I need a child component to override this method and return a cust ...

Using Dropbox for seamless navigation

My navigation using Dropbox is not redirecting to the selected page as expected. Below, I have provided code and a demo for your reference. App Routing Module import { NgModule } from '@angular/core'; import { CommonModule } from '@angular ...

Problem with synchronizing an Angular 2 application and the Angular 2 router

Currently dealing with a complex problem related to asynchronicity within an angular 2 application. The main issue arises when trying to reload information from the backend upon app refresh in the user's browser (such as F5/refresh). The setback occu ...

Dealing with multiple validation error messages in Angular Material 2

Working on a form using Angular Material 2, I am implementing a template-driven approach with an email input that requires two validators: required and email. The documentation for the input component (available at https://material.angular.io/components/co ...

Encountering a problem during the installation of Angular 4

I'm encountering issues during the installation of the @angular/cli package. Currently, my node version is v6.11.2 and npm version is 5.3.0. My first attempt to install it using sudo npm install -g @angular/cli resulted in an error message that kept ...

The AuthGuard (Guard decorator) is unable to resolve its dependencies according to Nest

My AuthGuard is responsible for checking the JWT token in controllers. I am trying to use this Guard in controllers to verify authentication, but I encountered the following error: Nest cannot resolve dependencies of the AuthGuard (?, +). Please ensur ...