-
Notifications
You must be signed in to change notification settings - Fork 25.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Input as Observable #5689
Comments
Hi @laco0416 - your English is fine, don't worry! I very much like this idea, and it's something we've discussed before. It also matches up nicely with #4062 (Observing view events) and #5467 (Observable child events from parents) It's important to remember that not everybody will want to use Observables (these people are missing out!), so we must provide options for both use cases, and so it's unlikely we'll make In the meantime, here's a basic (and very experimental!!! do NOT do this for real) implementation of this idea. Is this conceptually what you were thinking? http://plnkr.co/edit/Nvyd9IPBZp9OE2widOcW?p=preview |
I think it's a very bad idea to change input properties in a child component. Input properties should be "read-only". Your data should always flow from parent to child (and never in the reverse direction). |
@alexpods i believe the idea here is exactly that - its listening to the change in input properties as an Observable, not emitting values upstream, which is absolutely fine as far as I'm concerned. |
Thank you! I'm so relieved. Your |
@alexpods Me too at all.
I think in the same way as Rob. |
@laco0416 Ooh, sorry for misunderstanding. The phrase "if Input property was changed in the child component" confused me. |
I don't know if I should comment here or if I should open a new issue. Please let me know if I'm adding a request to the wrong place. I've been trying (but, until now, failing) to write a such a decorator, and then I stumbled upon @robwormald's plunkr, which works almost perfectly (but not quite). What got me excited by this approach was the fact that it is leveraging into the Having all lifecycle hooks available as Observables will help me Rx all the things ;-) |
Any updates on this? |
AFAIK, No. |
I know this is old, but this would be great! @robwormald Any word on this? |
I'd love to provide changing Unfortunately, Rob wasn't kidding when he said not to use this version of Has anyone managed a better implementation of |
@lephyrus While an official There is already a lifecycle event
Or, if you want something more reusable, you could create a base class that your component
... which could be used as follows:
I am using this approach until an official |
Thank you, @wmaurer. Your |
@lephyrus you're welcome, gärn gescheh ;-) I used |
@laco0416 close in favor of #13248 ? |
@DzmitryShylovich No. The feature proposed in this issue is read-only and event-driven data passing. |
|
Thank you @wmaurer for a good example. I have one question though. I would like to be able to use an object instead of a string as the observable. E.g.
However the this.updateChart and the ngOnChanges is not called. How can expand your sample from a simple string to observe an object instead? |
@ChrisWorks it should also work with objects:
I do this very often, so if this doesn't work, I'd guess there's a problem with the input to your component somewhere. |
Hi @wmaurer, thanks for the reply. Would you be able to expand your sample with a working version where you use a "config" object? I simply cant get mine to work. A sample Git repo? :) |
@ChrisWorks it really should just work the way it is. |
+1 Such a fundamental use-case, can't believe it hasn't been sorted yet! |
|
Is there any news on this? I think this is highly relevant for component-based architecture with inputs which can arrive and change at any time. In my case it's almost always to trigger some api call once all input values are present and then whenever either one changes. My solution is to use two or more local <some-cmp [itemid]="activeItemId$ | async" [userId]="activeUserId$ | async"></some-cmp> @Input() set itemId (id){this.itemId$.next(id)};
@Input() set userId (id){this.userId$.next(id)};
itemId$ = new BehaviourSubject$(null);
userId$ = new BehaviourSubbject$(null);
ngOnInt(){
combineLatest([
this.itemId$.pipe(filter(item=>!!item)),
this.userId$.pipe(filter(item=>!!item))
]).pipe(
debounceTime(10),
switchMap(...)
).subscribe(...)
} |
I'm assuming part of the delay getting this feature is related to change detection and ensuring everything works as efficiently as possible within change detection cycles. But clearly those nuances are the whole reason why we need framework support for something like this in the first place. I'd even be fine with observable lifecycle hooks to solve this right now. Just tell me 'reactively' when
Then in the template:
In fact if injected services were notified with a hook for A big advantage of this method is you won't run through your 'observable chain' until all the inputs are initially set and/or changed later. Let's say your component has three @input() property values that you've shoehorned into BehaviorSubject instances. You also have an injected service providing some other value. If you combine everything using One of the best parts of 'early angular' was they just went for it and made mistakes and told us 'sorry we changed the way this works'. I'm sure I'm not the only person that just wants some way to do it - even if it changes later. PS. Excuse my lack of imagination right now coming up with a smarter example that combined multiple observables. |
Thank you for submitting this feature request. The team has reviewed the feature request and has decided not to move forward with it. Turning inputs into Observables would more tightly couple Angular with RxJS, and we don't want to further couple with RxJS until we can discuss more broadly how we can utilize streamable / subscribeable APIs in a library agnostic way. You can see the related issue list for more information. |
well, that's very disappointing |
You broke my heart |
So back to reinventing the wheel every time I need to do this - in a slightly different way each time :-( |
At least it's fair, even too late. |
I feel that this decision is wrong in many ways.
I hope this decision is reverted soon and Angular will return to it's declarative reactive path instead of holding on to partly forcing users to use error prone imperative reactiveness. |
Well, that's a disappointing decision. I don't at all agree with the reasoning, you already coupled Angular with rxjs years ago and kinda left those actually utilizing it in the middle of the road, refusing to address the pain points for years until finally giving up altogether. I'm not moving away from Angular, I'm way too deep in, but man, it's sad to see what has become of this framework (and I've been here since the early alphas!), the excitement is all but gone. I can't remember the last release that actually improved developer quality of life. I really hope that at some point Angular will at least provide enough extension points to properly integrate features such as this one without having to resolve to hackarounds. |
Over 99% of messages here have never been responded to by a team member. In fact, there are only five (5) replies by team members, the first one being 5 years after opening the issue: 2020-04-27, by mgechev; 2020-04-28, by mgechev; 2020-05-18, by mgechev; 2021-01-07, by mhevery; 2021-05-27, by JoostK, off-topic. After over 6 years, 250 upvotes and 300 comments, the issue gets closed with a generic comment of three and a half lines in size, by a person who has never before participated in the discussion. Apparently, respect doesn't include responding to the most popular issue with hundreds of ideas?
Extend the courtesy and respect to everyone? Nah. Just close it with a stock reply after six years.
But at least there's a way to combat disrespect. Thank you, Angular! |
Probably everyone is anxiously awaiting what will follow as the next step. Currently, ~ 3/4 has been done, and ~ 1/4 is missing. Is it possible to think realistically about some magic idea that will connect the current state with some new all-embracing solution without massive breaking changes? After all, everything speaks in favor of the idea of finishing the remaining ~ 1/4 (like observable inputs, observable lifecycle hook streams, cold event template streams, ...), especially when many things it is not possible to move forward only by community efforts because changes are required at the internal level (compiler, ...). The current position of the Angular team does not make sense for this topic. |
This request wasn't about turning inputs into Observables, so it would not have increased coupling between Angular and rxjs. All we were asking for was an option, one that would have reduced lots of boilerplate in our code and made us happier to use Angular. Given that the compiler only includes code one is actually using in the final build, it wouldn't have even had any effect on those who didn't want to use it. It would have been nice if at least we could write libraries to provide this feature. Yet all the libraries in this thread either have problems with boilerplate, subscription leaks, or stopped working due to Angular updates. |
Why is this discussion necessary? Why can't Angular just continue to use streamable / subscribable implementation of RxJS? If we do need this discussion, then can we get on that? This is just kicking the can down the road, not actually addressing the request raised in this issue. |
You don't have to tightly couple it to Also, if you're wanting to move away from a tight coupling on rxjs (which I don't get the motivation behind at all), you're going to need to implement some sort of "ObservableFactory" anyway. Please reconsider. If you don't, at least give us more rationale. There are so many ways to solve the reason you gave for closing it. |
@angular/common @angular/elements @angular/forms @angular/router: "Am I a joke to you?" |
Thanks for all the discussion here. We just want to be clear that though we closed this issue, we are aware that it's a highly wanted feature. We aren't just ignoring it and do plan to address the feature need. We looked at this issue as a team and during our discussion, we decided that just implementing Observable for Inputs does have some drawbacks that we need to consider. We have no plans to divest in RxJS. We just were uncertain that in this case Observable was the best choice for streamable implementation as it has a lack of await support. Based on this feature request, we want to look at subscribable / "stream" based APIs in Angular holistically rather than just at this one issue in isolation, which is why the list of cross cutting issues related to this was posted. There will be a future feature proposal for streamables and component interaction that looks at this need as a whole. We will post a link to that feature request / issue on this thread once it's created. |
@jessicajaniuk And do you have a (rough) timeline for that proposal? This is understandably frustrating for every user, because the crack in the door is kept open for a magical candy future where it will be addressed. That time hasn't come in the past six years(!), and without any meaningful statement, I doubt people will believe it'll happen in the next ten years either (I certainly don't). I also don't understand why the team chooses to do all of these things (assuming that they are in fact being done) behind Google curtains rather than transparently out in the open. If the team truly is discussing these plans behind the scenes, there are so many ways to do so while keeping the community informed (even if you keep us read-only). |
@jessicajaniuk This sounds promising, and at the same time, it seems that the Angular team already has the basis of the proposed concept. If this is true, then the entire Angular community would very much welcome the publication of at least the basic building blocks of this concept and principled logic in the relatively foreseeable future. Is it possible to consider, say, about 4 - 6 weeks? |
Angular Component already has dependency on rxjs because of I propose following solution without any breaking changes Input as observable could exposed as same as current The API could like
And it could be used in template as any other input,
Component Consumer does not need to worry about, whether component's input is defined using |
If component author wants values as they arrive he can use @ObservableInput() name = new Subject(); If component author wants values only when they are provided by template @ObservableInput() name = new ReplaySubject(1); If component author wants have a default value also then he can use @ObservableInput() name = new BehaviorSubject(default_value); |
In the thread's spirit of half-assed third-party solutions to this common problem, I present my 30 line implementation: neo-observable-input. AFAIK unlike all other solutions proposed, this isn't a hack and it works with input typechecking in templates. Usage: import { Component, OnChanges } from "@angular/core";
import { ObservableInputs } from "neo-observable-input";
@Component({ template: "" })
export class ExampleComponent implements OnChanges {
private readonly inputs = new ObservableInputs();
@Input()
color: string;
color$ = this.inputs.observe(() => this.color);
@Input()
count: number;
count$ = this.inputs.observe(() => this.count);
ngOnChanges() {
this.inputs.onChanges();
}
} |
Let me quickly follow up here as well. As we've discussed in the past, the community is very split when it comes to using less or more RxJS with Angular. The majority of folks on GitHub are advanced developers who feel comfortable with RxJS, which makes the feedback we get here a bit more skewed towards more RxJS. Additionally, we're mindful of the JavaScript we ship as part of the critical loading path of an application. Having RxJS as a hard dependency automatically adds extra KBs. That's why we want to explore the alternative of making RxJS optional for It's also essential for us to provide an ergonomic solution for people who want to embrace a more declarative and expressive development style with RxJS. We can do this without introducing additional coupling with RxJS. For example, we could look into the shape of the input and treat it differently if it is observable-like. This way, we can avoid a hard dependency on RxJS, and we'd also support more advanced use cases. That said, we have many solutions in mind, and this thread offers tens of other exciting options to explore. We closed the issue because of two main reasons:
Since we want to set more realistic expectations in the future, we will share our plans for more ergonomic RxJS APIs when we prioritize that project. We'll make sure to follow up with an RFC and other resources that capture prior work and suggestions from the community to ensure we cover all the requirements of folks. Until we get there, I'd recommend using the community solutions that already exist and follow the roadmap for updates. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Sorry, I'm not good at English.
@Input
property values are provided by parent component. The changes come asynchronously.And if Input property was changed in the child component (it has the property as own property) , its change detector never notice it.
Goal
Proposal
Above code does not work. Currently, to receive input as
Observable<T>
, I must write it like below.Example: http://plnkr.co/edit/BWziQygApOezTENdTVp1?p=preview
This works well, but it's not essential. Parent's input data is a simple data originally.
I think this proposal make us happy.
Thanks.
The text was updated successfully, but these errors were encountered: