How to access parent slider variables in an Angular component

I've developed a slider as the parent component with multiple child components.

See the demo here: https://stackblitz.com/edit/angular-ivy-gcgxgh?file=src/app/slide2/slide2.component.html

Slider in the parent component:

 <ng-container *ngFor="let ques of current_slide_lists; let i = index">
    <div class="mySlides animated fadeInRight">
      <app-slide1 *ngIf="ques == 'Multiple choice'"> </app-slide1>
      <app-slide2 *ngIf="ques == 'Single choice'"> </app-slide2>
    </div>
  </ng-container>

Child Component 1:

<p>
  Multiple choice Questions :
  <br />
  <input
    #optA
    class="form-check-input"
    type="checkbox"
    name="answer"
    id="answer_A"
    value="A"
  />
  Option 1
  <br />
  <input
    #optB
    class="form-check-input"
    type="checkbox"
    name="answer"
    id="answer_A"
    value="A"
  />
  Option 2
  <br />
  <input
    #optC
    class="form-check-input"
    type="checkbox"
    name="answer"
    id="answer_A"
    value="A"
  />
  Option 3
</p>

Child Component 2:

Single choice choice Option :
<br />
<input
  [(ngModel)]="select_option"
  type="radio"
  name="answer"
  id="answer_A"
  value="A"
/>Option 1
<br />
<input
  [(ngModel)]="select_option"
  type="radio"
  name="answer"
  id="answer_A"
  value="B"
/>Option 2
<br />
<input
  [(ngModel)]="select_option"
  type="radio"
  name="answer"
  id="answer_A"
  value="C"
/>Option 3

There will be various child components, with these two examples showcasing different functionalities. I am relatively new to Angular and trying to figure out how the parent component can access and manipulate data from the child components when needed. Specifically, if a user interacts with the child components (e.g., selecting checkboxes), I want the selected values to be accessible in the parent component. Any suggestions on passing and managing data between parent and child components are greatly welcomed. Thank you.

Answer №1

When it comes to communication between child and parent components in Angular, the preferred method is using an @Output. This allows you to emit custom events as needed.

In the child component:

@Output() dataChange= new EventEmitter<any>();

//you can emit events like this
this.dataChange.emit({data:'hello',value:'other',count:0});

In the parent component:

<app-slide1 (dataChange)="makeSomething($event)"...>
makeSomething(data:any)
{
   console.log(data)
}

You can also access child components from the parent using a template reference variable and ViewChildren.

<app-slide1 #slide *ngIf="ques == 'Multiple choice'"> </app-slide1>
<app-slide2 #slide *ngIf="ques == 'Single choice'"> </app-slide2>

ViewChildren('slide') slides:QueryList<any>

//for example, accessing a variable in the first slide
const value = slides.first.anyVariable;

However, when using ViewChildren, you cannot use *ngIf directives.

[style.display]="!condition?'none':null"

Another approach is passing complex objects as input.

In the parent component:

obj: any = {};

<app-slide1 [dataObject]="obj" ...> </app-slide1>
<app-slide2 [dataObject]="obj" ...> </app-slide2>
 

In the child component:

@Input() dataObject;
//somewhere within the component
this.dataObject.newProperty = "Hello";

//assigning a new object to dataObject is not allowed
//this.dataObject = ...

Update

A special case arises when the child components are forms.

First, you need to decide whether to use ReactiveForms with FormGroups or Template-driven forms with [(ngModel)].

In both cases, you pass either a FormGroup or an object as input.

Example using FormGroup:

//in parent
form = new FormGroup({
    property: new FormControl()
})
<app-slide1 [control]="form.get('property')"...></app-slide1>

//in child
control: FormControl
@Input('control') _control(value)
{
    this.control = value as FormControl;
}
<input [formControl]="control">

Example using ngModel:

//in parent
obj = {property: null};

<!--passing the entire object-->
<app-slide1 [data]="obj" field="property" ...></app-slide1>

//in child
@Input() data
@Input() field
<input [(ngModel)]="data[field]">

Both approaches involve passing an object, ensuring that changes made in the child reflect in the parent due to the shared object.

For ReactiveForms, a "setter" is used to handle casting of the control because TypeScript does not recognize FormControls directly.

When utilizing ngModel for managing a single property, two-way binding can be implemented for seamless updates.

In the child component:

@Input() data
@Output() dataChange = new EventEmitter<any>()
<input [ngModel]="data" (ngModelChange)="dataChange.emit($event)">

This enables a concise syntax in the parent component for easy assignment.

<app-slide1 [(data)]="obj.property" ...></app-slide1>

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

Error encountered when trying to update tree structure in TypeScript with new data due to incorrect array length validation

I have encountered an issue with my tree data structure in TypeScript. After running the updateInputArray(chatTree); function, I am getting an “invalid array length” error at the line totalArray.push(iteratorNode.data);. Furthermore, the browser freeze ...

Enable the use of empty spaces in ag-grid filter bars

I'm experiencing an issue with the ag grid filter. It seems to be disregarding white spaces. Is there a way to configure the grid to recognize blank spaces in the filter? Any suggestions for resolving this issue? Where can I find the option to accept ...

Revamp the Bootstrap Form Upload feature

I am looking to redesign the Bootstrap Form Upload field. The main reason behind this is that in Bootstrap, the file upload field is treated as one single component, making it impossible to separate the file upload button from the file upload text. The fi ...

Error NG0304: The element 'mat-select' is not recognized in the template of the 'LoginPage' component

After creating a basic app, I decided to incorporate Angular Material into my project. The app in question is an Ionic 6 / Angular 14 app, however, I encountered an error while attempting to implement mat-select: https://i.sstatic.net/Quc53.png To addres ...

Monitor the status of your Angular CLI build with real-time notifications

Encountered an interesting issue while trying to integrate the 'webpack-notifier' plugin into a new Angular 7 application. The goal was to have balloon notifications for build failures when running 'ng build --watch' in the console. TL ...

Generic Typescript Placeholder Design

Imagine you have the following data: const dataA = { name: "John", age: 25, attributes: {specificA: "hello", specificA2: 14, nonspecific:"Well"}, } const dataB = { name: "Lisa", age: 38, attributes: {spe ...

I've been working on setting up a navbar in React/typescript that links to various routes, but I've hit a snag - every time I try to create a link

import React from 'react' import { Link } from 'react-router-dom' export default function NavBar() { return ( <div className='NavContainer'> <link to='/home'>Home</link> <l ...

How to Use ngFor to Create a Link for the Last Item in an Array in Angular 7

I need help with adding a link to the last item in my menu items array. Currently, the menu items are generated from a component, but I'm unsure how to make the last item in the array a clickable link. ActionMenuItem.component.html <div *ngIf= ...

Transforming a current angular 2 project to incorporate angular CLI

I was working on a project which wasn't set up using the 'ng new' command, but rather I followed the steps outlined in the quickstart guide. However, whenever I try to use an angular CLI command like 'ng generate', I keep getting t ...

Can a generic type be utilized to instantiate an object?

In my code, I have a class named Entity as shown below: class Entity { constructor(readonly someValue: string) {} someFunction() {} } Now, I am trying to create a class that will handle these entities and be able to create instances of them. In or ...

How to verify that the user is using the most up-to-date version of the application in React Native

Currently, I am focused on the application and have implemented API endpoints that return the latest version along with information on whether the update is mandatory. Within the application flow, a GET request is sent to these API endpoints to check the ...

Tips for manually triggering change detection in Angular 2+

I am presenting a component with the following structure: import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app', moduleId: module.id, template: ` <input [value]="a" (change)="onValidate ...

Using TypeScript: Defining function overloads with a choice of either a string or a custom object as argument

I'm attempting to implement function overloading in TypeScript. Below is the code snippet I have: /** * Returns a 400 Bad Request error. * * @returns A response with the 400 status code and a message. */ export function badRequest(): TypedRespons ...

Issues arise when attempting to enforce type-safety in TypeScript while using the JSON.parse

Is it possible that type-safety is compromised in TypeScript when dealing with JSON parsing? I should be triggering an error, but I'm not: interface Person { name: string } const person: Person = somePossibleFalsey ? JSON.parse(db.person) : undefi ...

Presenting SQL information in a hierarchical Angular grid for easy visualization

As a newcomer to Angular, I have a requirement to display data in a multilevel/hierarchical Angular Grid. The data is retrieved from a SQL Database using a query with arguments provided in the where clause. Some questions that come to mind are: Is there ...

Deep copying with Object.assign can lead to unexpected issues

I am currently working with an object array that needs to be transformed before it is sent to the controller. Here is the Angular code snippet I am using: sourceObjArray: SourceObject[] = [..]; targetObjArray: SourceObject[]= []; targetObjArray = object. ...

Why does TypeScript assign parameters in the opposite direction when assigning callbacks?

When a function is called with an argument, the argument type is matched to the parameter type. This means that the argument type must be the same as, or more specific than, the parameter type. For example: const foo = (bar: string | number) => { con ...

A method for increasing a counter using only an instance of a class or function without accessing its methods or properties in Javascript

Looking at the task ahead, let increment = new Increment(); I have been tasked with creating a Javascript class or function called Increment in order to achieve the following: console.log(`${increment}`) // should output 1 console.log(`${increment}`); ...

Is there a way to retrieve the initial item of a JSON array from an HTML document using Angular 2?

Within the src/assets/ directory, I have a json file called product.json with the following structure: [ { "images": "http://openclipart.org/image/300px/svg_to_png/26215/Anonymous_Leaf_Rake.png", "textBox": "empty", "comments": "empty" }, { "i ...

A React component featuring a nested map function should always include a "unique key" prop for each element

I am trying to figure out how to assign a proper Key Value in this component: {var.map((building, index) => { const handles = building.buildingVertices.map((point) => { return ( <DrawingHandle key={`${i ...