How to change the type of an @Input variable with an other chained decorator

Viewed 25

I would like to transform an @Input into a stream. This is what I mean:

data$ = new Subject<number[]>();
@Input() set data(value: number[]) {
    this.data$.next(value);
}

Works like a charm. Now I can use this stream everywhere in my code. But I was wondering if there is a way to simplify this, with a @Decorator for example:

@Input() @AsObservable() data: Observable<number[]>

even better

@Input('data') @AsObservable() data$: Observable<number[]>;

But now angular starts complaining about the number[]> vs Observable<number[]>

myNumbers = [1,2,3,4];
...
<app-my-foo [data]="myNumbers"></app-my-foo>

Type 'number[]' is missing the following properties from type 'Observable': source, operator, lift, subscribe, and 2 more.

DEMO

Is there a way to fix this issue with my decorator approach? Or should I go for a different approach, for example stick to the ngOnChanges lifecycle function? Any suggestions?

Update: Usage example:

@Component({ selector: 'app-foo', ... })
export class FooComponent implements OnInit {
    @Input() isBaz = false;
    @Input<number[]>('data') @asObservable<number[]>() data$: Observable<number[]>;
    @Input<boolean[]>('state') @asObservable<boolean[]>() state$: Observable<boolean[]>;

    ngOnInit() {
        combineLatest([this.data$, this.state$]).pipe(...).subscribe(...);
    }
    ...
}
1 Answers

Using stream like subject is mostly use when you store something on the service, and you want all places to notify when it changed. but here you're using @Input - meaning you're inside a component - so there's no need to use subject because the template will change every time you change the @Input value. so I recommend you to store it as is - @Input() data: number[]

but if you need the stream for some reason - you can pass it from parent component like that:

myNumbers = of([1,2,3,4])
<app-my-foo [data]="myNumbers"></app-my-foo>

and in your child component:

@Input('data') @AsObservable() data$: Observable<number[]>;

good luck :)

Related