Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign upProposal: Input as Observable #5689
Comments
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
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). |
This comment has been minimized.
This comment has been minimized.
|
@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. |
This comment has been minimized.
This comment has been minimized.
Thank you! I'm so relieved. Your |
This comment has been minimized.
This comment has been minimized.
|
@alexpods Me too at all.
I think in the same way as Rob. |
This comment has been minimized.
This comment has been minimized.
|
@laco0416 Ooh, sorry for misunderstanding. The phrase "if Input property was changed in the child component" confused me. |
This comment has been minimized.
This comment has been minimized.
|
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 ;-) |
This comment has been minimized.
This comment has been minimized.
|
Any updates on this? |
This comment has been minimized.
This comment has been minimized.
|
AFAIK, No. |
This comment has been minimized.
This comment has been minimized.
|
I know this is old, but this would be great! @robwormald Any word on this? |
This comment has been minimized.
This comment has been minimized.
|
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 |
This comment has been minimized.
This comment has been minimized.
|
@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 |
This comment has been minimized.
This comment has been minimized.
|
Thank you, @wmaurer. Your |
This comment has been minimized.
This comment has been minimized.
|
@lephyrus you're welcome, gärn gescheh ;-) I used |
This comment has been minimized.
This comment has been minimized.
|
@laco0416 close in favor of #13248 ? |
This comment has been minimized.
This comment has been minimized.
|
@DzmitryShylovich No. The feature proposed in this issue is read-only and event-driven data passing. |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
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? |
This comment has been minimized.
This comment has been minimized.
|
@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. |
This comment has been minimized.
This comment has been minimized.
|
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? :) |
This comment has been minimized.
This comment has been minimized.
|
@ChrisWorks it really should just work the way it is. |
This comment has been minimized.
This comment has been minimized.
|
+1 Such a fundamental use-case, can't believe it hasn't been sorted yet! |
This comment has been minimized.
This comment has been minimized.
|
Any update on when this will be released so far the |
This comment has been minimized.
This comment has been minimized.
|
I think official support would be more mature, will guarantee continuous support across versions and smoother dev experience/will encourage developers to go full rxjs* and optimize with on push change detection (this should be a core groundbreaking feature to my opinion) *without compromizing compatibility with non observable inputs or needing extra boilerplate for hybrid inputs ie: setter calling next on subject |
This comment has been minimized.
This comment has been minimized.
|
Used observable-input in angular 4, 5 and 7 with and without aot. It seems to work well. I'm pretty sure I vaguely knew what I was doing when I wrote it. |
This comment has been minimized.
This comment has been minimized.
|
hope they 'll add it in the framework and encourage its usage 2 weekly downloads npm is not enough compared to the advantages it offers xD if they add it I bet people will see that it's simple to follow that approach |
This comment has been minimized.
This comment has been minimized.
|
I propose following API for async input with user defined decalre function AsyncInput(bindName?:string) : <T extends Observer>(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<T>) => anyusers could just use it as @AsyncInput()
asynchronusProperty1 = new Subject();
@AsyncInput()
asynchronusProperty2 = new ReplySubject(1);
@AsyncInput()
asynchronusProperty3 = new UserObserver(); // where UserObserver implement `Observer` interfaceAngular internal can just call |
This comment has been minimized.
This comment has been minimized.
|
Don't forget |
This comment has been minimized.
This comment has been minimized.
|
This should be combined with constructor @input injection to make it even more awesome. This way we could fix "strictPropertyInitialization" in a very elegant way: class MyComponent {
inputData$: Observable<Data>;
constant: string;
constructor(
@Input() inputData$: Observable<Data>,
@Input() constantString: string
) {
this.inputData$ = inputData$;
this.constant = constantString;
}
} |
This comment has been minimized.
This comment has been minimized.
|
@benneq just worth noting it could be as small as: class MyComponent {
constructor(
@Input() private inputData$: Observable<Data>,
@Input() private constantString: string,
) {}
} |
This comment has been minimized.
This comment has been minimized.
|
@maxime1992 yep, although you'd need a separate decorator for inputs as observables to distinguish between the case of observables being passed from one component to another. |
This comment has been minimized.
This comment has been minimized.
|
@benneq @maxime1992 Parameter names are not part of decorator metadata, how do you get it mapped? |
This comment has been minimized.
This comment has been minimized.
|
@trotyl I guess you could then use |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I don't know if someone already posted this solution but this is a fairly good workaround |
This comment has been minimized.
This comment has been minimized.
|
@ElianCordoba This is not about HTML |
This comment has been minimized.
This comment has been minimized.
|
That's a different, but similarly painful issue @ElianCordoba. #13248 |
This comment has been minimized.
This comment has been minimized.
|
I think this is a pseudo-requirement. Firstly, the input decorator can accept an Observable type value, secondly, if the component requires an observable as input, it should be explicitly throw error when received a non-observable value instead of quietly convert it to Observable type value. It is quite similar to implicit type conversion in javascript, may be confused even cause bug and difficult to found. |
This comment has been minimized.
This comment has been minimized.
|
That's not about silencing wrong input. It's about exposing a common interface across components (which is non-observable input). This gives you the freedom to introduce rx functionality without breaking its interface in the outside world. Another benefit is mainly lifting mutability and internal state since everything will be a transformation of the input which makes on push change detection from that point onwards a no brainer. On the contrary, exposing, an interface that requires observables sounds clunky and forcing people to provide of(value) just because your component said so sounds weird to me. |
This comment has been minimized.
This comment has been minimized.
|
Plus it's not about silent conversion, it's an API to subscribe to changes via rxjs. Given angular.http and the router provide observables it's super awkward that input change handling does not, unifying the worlds of callbacks and RxJs requires too much boiler plate. |
This comment has been minimized.
This comment has been minimized.
|
Not that I don't love some of the clever solutions above, but sometimes just a slight reorganization of the 'standard' way to do it is enough to solve the real problem here which is lack of clarity / clumsiness. Plus I'm still hoping for an 'official' post-ivy way to do this someday.
Then you can just put something like Either
This not only helps with code clarity but because I'm grouping all the inputs together I can easily see what's a 'pure' observable input by just typing You can go further with type safety with this (mostly this is just for fun).
Then you don't need to explicitly specify the type of the @input property.
I could have made an ObservableInputs interface for the component to enforce |
This comment has been minimized.
This comment has been minimized.
|
@simeyla Too much boilerplate. |
This comment has been minimized.
This comment has been minimized.
|
I decided to put my own decorator out there. It's my first npm package so I'm sure there's something I'm missing, but here it is: https://www.npmjs.com/package/@ng-reactive/async-input Installation
Usage
|
This comment has been minimized.
This comment has been minimized.
|
@mfp22 really nice, I see no reason why something like this shouldn't be built in. FYI, the github link on npm for the package is outdated, it goes to here: https://github.com/mfp22/async-input/tree/master/projects/async-input |
This comment has been minimized.
This comment has been minimized.
|
I see this is pretty old issue but the feature is pretty amazing and I'm really exited to see it in Angular. What is even cooler is that with observable inputs you do not need @Component({...})
class MyReactiveComponent {
@ObservableInput() prop: Observable<string>; // Whatever syntax may be...
// emits [prevValue, currValue] and no OnChanges hook yay!!
propChanges$ = this.prop.pipe(pairwise());
} |
This comment has been minimized.
This comment has been minimized.
|
https://github.com/rx-ts/ngrx/blob/master/src/utils/decorators.ts#L56-L124 It's my personal implementation, it works perfectly and pretty awesome, if we can have it build-in, that is really cool. |
This comment has been minimized.
This comment has been minimized.
|
I've published the solution I've used personally in my projects as a npm package: https://github.com/futhark/ngx-observable-input Installation
Usage...
<image-item [url]="currentImageUrl"></image-item>import { Component, Input } from "@angular/core";
import { ObservableInput } from "ngx-observable-input";
import { Observable } from "rxjs";
@Component({
selector: "image-item",
template: `<img [src]="url$ | async" />`
})
export class GalleryComponent {
@ObservableInput() @Input("url") public url$: Observable<string>;
...
} |


Sorry, I'm not good at English.
@Inputproperty 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.