To illustrate the scenario before linkedSignal and why it’s best for the scenario, let’s say there’s a requirement to display a greeting that is composed of first and last names. Those two values will be provided by some input fields. The greeting can be populated automatically when names are provided or manually by setting its value.
With just computed, once first and last name values are provided by some input fields, the corresponding functions update the signals firstName and lastName. displayName is a computed property that combines the two values.
We have two variables for greetings: greetings for setting the greeting manually (overriding existing values), and computedGreetings that automatically combines the a greeting with the display name. The reason for the separation is that computed variables are read-only (we can’t modify its values)
This works, but it can be simplified with linkedSignal
firstName = signal('');
lastName = signal('');
displayName = computed(() => this.firstName() + ' ' + this.lastName());
greetings = signal('');
computedGreetings = computed<string>(() => 'Hello ' + this.displayName());
setFirstname(v: string) {
this.firstName.set(v);
}
setLastname(v: string) {
this.lastName.set(v);
}
setGreetings(v: string) {
this.greetings.set(v);
}
constructor() {
// This simulates the part where we need to get either of the greetings. Since we have two sources, we need to know which are non-empty.
effect(() => {
let greetings = this.greetings();
if (greetings === '') {
greetings = this.computedGreetings();
}
console.log('greetings', greetings); // greetings Hello test1 test2
});
}
triggerChanges() {
this.setFirstname('test1');
this.setLastname('test2');
}
With linkedSignal, we don’t need two versions of greetings since linkedSignal returns a writable signal. Basically, it provides the writability of a regular signal and reactivity of a computed signal.
firstName = signal('');
lastName = signal('');
displayName = computed(() => this.firstName() + ' ' + this.lastName());
// greetings is like a regular and computed signals combined into one
// its type is WritableSignal<string>
greetings = linkedSignal(() => {
return 'Hello ' + this.displayName();
});
setFirstname(v: string) {
this.firstName.set(v);
}
setLastname(v: string) {
this.lastName.set(v);
}
setGreetings(v: string) {
this.greetings.set(v);
}
constructor() {
effect(() => {
console.log('greetings', this.greetings());
});
}
triggerChanges() {
this.setFirstname('test1');
this.setLastname('test2');
}