Utilizing Angular signals to facilitate data sharing among child components

I have a main component X with two sub-components Y and Z. I am experimenting with signals in Angular 17. My query is how can I pass the value of a signal from sub-component Y to sub-component Z?

I have attempted the following approach which works initially, but fails to update when the signal's value changes.

subComponentY.component.ts

 export const data = signal<any>('');

 fetchData() {

    this.loading = true;
    
    const functions = getFunctions(getApp());
    connectFunctionsEmulator(functions, 'localhost', 5001);

    const getInfo = httpsCallable(functions, 'getInformation')
    getInfo(this.url.value)
    .then( (result: any) => {
      // result.data returns an object
      data.set(result.data);
      console.log(data());
    })
  }

subComponentZ.component.ts

import { data } from '../subComponentY/subComponentY.component';

data_ = data;

subComponentZ.component.html

<p class="">{{data_().data.title}}</p>

Although the console displays the updated signal data, the HTML template does not reflect these changes. Any suggestions?

Answer №1

You have the option to utilize it as an @Input, see the functional example provided below!

parent

import { CommonModule } from '@angular/common';
import { Component, signal } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import 'zone.js';
import { TestComponent } from './test/test.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, TestComponent],
  template: `
    <app-test [item]="item"></app-test>
  `,
})
export class App {
  item = signal<any>('');

  ngOnInit() {
    this.retrieveFileInformation();
  }

  retrieveFileInformation() {
    // this.loading = true;

    // const functions = getFunctions(getApp());
    // connectFunctionsEmulator(functions, 'localhost', 5001);

    // const getInfo = httpsCallable(functions, 'getInformation')
    // getInfo(this.url.value)
    // .then( (result: any) => {
    // result.data return object
    // mock the API call!
    this.item.set({ data: { title: 'hello!' } });
    setTimeout(() => {
      this.item.set({ data: { title: 'hello world!' } });
    }, 2000);
    console.log(this.item());
    // })
  }
}

bootstrapApplication(App);

child

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

@Component({
  selector: 'app-test',
  imports: [CommonModule],
  template: `
    <p class="">{{ item()?.data?.title | json }}</p>

  `,
  standalone: true,
})
export class TestComponent implements OnInit {
  @Input() item!: Signal<any>;
  constructor() {}

  ngOnInit() {}
}

Check out the StackBlitz demo here!

Answer №2

Avoid using @inputs for signals in your components. Signals are most powerful when used for cross-component communication, rather than just establishing parent-child relationships.

To prevent unnecessary updates and potential issues, consider creating a service to share the signal between components instead.

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

Issue with ngSubmit not being triggered in Angular Reactive Form

Just jumping into Angular and experimenting with reactive forms while following a tutorial. Struggling to get my ngSubmit() function to work - the submit button doesn't respond no matter what I try. Spent ages trying to troubleshoot but no luck so far ...

Angular: InjectionToken for service injection causes issue

Angular version: 4.4.6 Edit: This example may appear complex and not relevant to some readers. TL;DR: I encountered a problem where my service could not be dynamically injected because it was not provided by any module. This confusion stemmed from trying ...

Tips on sending a list via @Input using Angular5

I was seeking guidance on how to pass a list through an input. In my parent component, I have the following: list: Hero[] = [{Id: 2, Name: "Sll"}, {Id: 3, Name: "Sldsadasd"}] and in the HTML: <app-add-hero list="{{list}}" hero={{hero}}></app-ad ...

Incorrect tsx date interpretation when dealing with years such as 0022

I am facing an issue with dates in tsx. The problem lies in the fact that when I set a date like 30/11/0022, it interprets the date as 30/11/1922, which is incorrect. Here is the input element I have in tsx: <FormikField name="Birthdate" disa ...

What is the best RxJS operator to implement additional transformations following mapping?

this.service.retrieveObject(id).map((object)=>{ return transformation1(object); }) .map((object)=>{ return transformation2(object); }); In the following example, the second map call does not have access to the object ...

The error occurred while using NPM watch: ReferenceError: The variable "_" is not recognized in the file "../node_modules/angular-google-maps/dist/angular-google-maps.js" at line 1, column 1 (

I'm currently working with Angular and encountered an error in the console section of my browser after restarting my computer: Unhandled Promise rejection: _ is not defined ; Zone: <root> ; Task: Promise.then ; Value: ReferenceError: _ is not de ...

Having trouble loading static files in Django Angular framework? Specifically, images stored in the assets folder returning a

In my Angular project, I have an assets/image folder within the src directory where all my images are stored. Various components and child components in my app use these images like <img src"../../../assets/image/test.png">. After building my Angula ...

What events can cause all store states to be loaded when the page is altered?

I am currently utilizing ngrx/store, ngrx/effects, and ngrx/router. The implementation of my effects is structured as follows: @Effect() loadOneProduct$ = this.updates$ .whenAction(LOAD_ONE_PRODUCT) .switchMap(() => this.productService.loadOn ...

What is the method for utilizing an alias at the top within a subquery?

Is it possible to use an alias from the top query in a subquery? I am currently encountering an error with 'artc'. let myQuery = this.articles.createQueryBuilder('artc') .select(['artc.title']) .addSelect(qb => ...

What is the best way to remove all attributes from one interface when comparing to another?

Consider the following two interfaces: interface A { a: number; b: string; } interface B { b: string; } I am interested in creating a new type that includes all the keys from interface A, but excludes any keys that are also present in interface B. ...

Troubleshooting the issue of the Delete Service not functioning properly within Angular

ListStore.ts file export class ListstoreComponent implements OnInit { rawlist; name = ''; id = ''; storeid = ""; store: Store; constructor(private api: APIService, private router: Router, private route: ActivatedRoute, pri ...

Tips for differentiating between elements with identical values in an HTML datalist using Angular

My boss is insisting that I use a datalist in our website interface to select an employee, even though there's no way to determine if the user typed in the name or picked from the list. The challenge is that the list must only display full names, but ...

Adding a dynamic CSS stylesheet at runtime with the power of Angular and Ionic 2

Currently, I am working on creating a bilingual application using Ionic2. The two languages supported are English and Arabic. As part of this project, I have created separate CSS files for each language - english.css and arabic.css. In order to switch be ...

Retrieving the selected date from mat-datepicker into a FormControl

When creating a POST request to an API, I encountered an issue with the mat-datepicker field as it throws an error when inside the ngOnInit() call (since nothing is selected yet). Other fields like name, email, etc. work fine, but extracting a value from t ...

Extract the value from an array of objects

https://i.sstatic.net/fTShc.png Having some difficulty accessing the elements of an array. In order to assign a project name to a local variable projectName, I am seeking assistance with extracting the project name from the given JSON structure. Any hel ...

Organize the attributes of components on the following line in Visual Studio Code

Is there a method to configure the VS code formatter for Angular 2+ templates to ensure that attributes are wrapped in a new line? I prefer this formatting: <app [input1]="input1$ | async" [input2]="input2$ | async" (inputChanged)="set ...

How can certain properties be mandated while still permitting additional ones?

I am currently working on creating a function that requires one property as an argument, but could potentially have additional properties as well. Here is an example: interface Foo { bar: string; } function someFunc(obj) { // implement functional ...

A TypeScript array interface featuring an indexed structure along with the ability to access custom properties through string keys

I am looking to create an array of objects in which each object is indexed by numbers and can also be grouped under a specific key. Here's what I have so far: const myArray:ICustomArray = [] myArray.push(item) myArray[item.key] = item; However, I a ...

Converting JSX files to TSX files: a step-by-step guide

I am facing an issue with this particular component on the website. It is currently in .jsx format while the rest of the website uses .tsx files. I need to convert this specific component into a .tsx file. Can someone provide assistance or guidance? Despit ...

making GET and POST requests within a single function using Angular 2

How can I trigger an HTTP POST service call after a successful GET response? This is how I've implemented the GET call: import {Page, NavController} from 'ionic-angular'; import {Http, Headers} from 'angular2/http'; import ' ...