#Is banana in a box better than rxjs and signals
25 messages · Page 1 of 1 (latest)
Hi, it's really unrelated and arguing about some feature from angularjs is far from being the best way to prove being right.
It feels like they are mixing APIs like you could compare them: you can't.
banana in the box is a communication solution between components: rxjs and signals are not.
Yeah, that's what I figured too, trying to figure out the best way to explain it to him
He's mainly concerned about propagating changes in values into the template. Like, if we could just use a two way binding and regular Zone.js change detection why do we need rxjs/signals
(is his argument, not mine)
two way data binding is a channel for data.
You still need a data reference somewhere. It might be stored in a variable or a signal.
There is nothing wrong about storing it in a signal, you might even get benefits with computed signals.
But they do not want, well so...
But I do not understand why they mention rxjs: it's totally unrelated.
It would require snippets with/without to understand their logic.
Option 1
ParentComponent {
fruit = "orange"
changeFruit(input: string)
{
this.fruit = input;
this.changeDetectorRef.markForCheck(); // maybe needed??
}
}
ChildComponent {
@Input() fruit: string;
ngOnChanges(changes) {
if (changes.fruit) this.changeSomethingElse();
}
}
Option 2
ParentComponent {
fruit: BehaviourSubject<string>;
// or signal?
}
ChildComponent {
@Input() fruit: Observable<string>;
somethingElse = this.fruit.pipe(map(this.changeSomethingElse));
}
Something like this I guess
Obviously input bindings are used in both cases, but one is using a lifecycle hooks instead of rxjs
And a real example would probably be much more complex than this
For two way binding:
Option 1
ParentComponent {
fruit = "orange"
someParentFn(input: string)
{
this.fruit = input;
this.changeDetectorRef.markForCheck(); // maybe needed??
}
}
ChildComponent {
@Input() fruit: string;
@Output() fruitChange = new EventEmitter<string>();
ngOnChanges(changes) {
if (changes.fruit) this.changeSomethingElse();
}
someChildFn(input: string)
{
this.fruit = input;
this.fruitChange.emit(input);
}
}
Option 2
ParentComponent {
fruit: BehaviourSubject<string>;
// or signal?
someParentFn(input: string)
{
this.fruit.next(input);
}
}
ChildComponent {
@Input() fruit: BehaviourSubject<string>;
somethingElse = this.fruit.pipe(map(this.changeSomethingElse));
someChildFn(input: string)
{
this.fruit.next(input);
}
}
The issue is you are comparing apples with bananas. As called, two way data binding is for two way data binding.
So simple variables, signals or observables, if you need the child to get and emit data, choosing signals or observables is unrelated
Why is it apples and bananas?
In one example the change to the fruit are propagated and listened to in the child via ngOnChanges, in the other, the fruit changes are listened to through an rxjs subscription or pipeline
So either this.changeSomethingElse() modifies something else in the child imperatively, or it's done via the rxjs map operator
The point with 2way data binding is to send back the updated data from the child to the parent. If you need it, use it. But using signals or observables is unrelated to the requirement to emit some data back to the parent.
There might be choices about your data itself indeed, but that's unrelated to the communication itself between components.
The parent still has a reference to same BehaviorSubject it passed to a child, if the child nexts the subject, the parent can simply subscribe/pipe to the subject and get the updated data that way instead.
do not pass the transporter, pass the merchandise.
That's the best way to keep things simple.
And from my experience, 2 way data binding itself is not that common, i never used it in 6 years because the contract between a parent and a child might be always that simple.
Yeah, I haven't found it common either
So to clarify, you mean you'd rather pass through the event emitter rather than through the subject?
Yes
But to answer to the first question from your manager, he's right: do not pass a transporter as a way to send data back to the parent.
What about just the one way input binding?
If a parent changes the fruit, should the child do stuff imperatively within the ngOnChanges to respond to the fruit change, or should the child do a subscribe or pipe just once at the beginning
1 one or 2 way you should still consider using Signals as you can bind a signal to banana in the box, with 'model' signal in the child.
Then you can use all the signal API like computed or effect there to get derivated state or use side effects