Reputation: 2285
I have a parent component A
and two child components B
and C
. I'm testing signals with Angular 17. My question is how do I share the value of a signal from component B
to component C
?
I have tried the following and it works the first time but when the signal value changes it does not update.
componentB.component.ts
export const item = signal<any>('');
getFileInformation() {
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
item.set(result.data);
console.log(item());
})
}
componentC.component.ts
import { item } from '../componentB/componentB.component';
item_ = item;
componentC.component.html
<p class="">{{item_().data.title}}</p>
In the console I always get the new updated signal data, but in the HTML template it is not updated. Any ideas?
Upvotes: 2
Views: 3216
Reputation: 1
You should not use @inputs for signals. Power of signals is cross component communication not just parent-child relation.
You can create a service and share the signal between the components that way it avoids unnecessary updates and cause issues.
Upvotes: 0
Reputation: 57696
You can pass it as @Input
, working example 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.getFileInformation();
}
getFileInformation() {
// 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() {}
}
Upvotes: 0