0
votes

I have two components details and details-view.

In the details I have to pass obserwable by @Input() into second component.

Details Component

 res$: (id: number, type: string) => Observable<DetailsResponse[]>;
 constructor(private service: Service) {
  this.res$ = service.getData;
 }

Service

 getData(id: number, type: string): Observable<DetailsResponse[]>{
   const params = new HttpParams().append('typename', type);
   return this.http.get<any>('api/id', {params: params});
 }

Detalis-View HTML

<dwtalis-view [resources$]="res$"></dwtalis-view>

Detalis-Viev TS Component

@Input()
resouces$: Observable<DetailsResponse[]>

My question is how to subscribe and get the data from resources$ observable in the detalis view component. Subscribing this object retunrs error "resources$ is not a finction can not subscribe"

3
Assuming this isn't a typo: this.res$ = service.getData is just passing the function definition. If you actually want an observable, you need to execute the function this.res$ = service.getData(). Alternatively, if you do mean to pass the function definition then your typing for resource$ is wrong, and it should be (id: number, type: string) => Observable<DetailsResponse[]> to match res$ from the parent component - Vlad274
like vlad said you are passing function instead of observable. In your case you need to call that resources$() function to get the observable out from it. resources$().subscribe. - hunterTR

3 Answers

2
votes

Apart from the typo at service.getData(), it is also important to know when input properties are available to be bound. Input's are not set in the constructor, they are available in the ngOnChanges life cycle hook every time an input changes. or in ngOnInit if you want to bind just the first time it is received.

https://angular.io/guide/lifecycle-hooks

1
votes

The typing doesn't match. res$ is a function (id: number, type: string) => Observable<DetailsResponse[]>, but resouces$ is an observable Observable<DetailsResponse[]>;

Based on your comments, you need to pass a function because the arguments aren't available in the parent component. So, you need to accept a function as @Input and then execute it in the child component.

Child Component

@Input()
resouces$: (id: number, type: string) => Observable<DetailsResponse[]>;

// Use ngOnInit since @Input properties are populated at this time
ngOnInit() {
    // Example arguments
    this.resouces$(this.id, this.type).subscribe(results => {
        // Do whatever you need to do with the results
        console.log(results);
    })
}
0
votes

You can change the DetailsViewComponent like the following code

export class DetailsViewComponent implements OnInit, OnChanges {

  @Input() resouces$: (id: number, type: string) => Observable<DetailsResponse[]>;

  constructor(
  ) {}

  ngOnInit() {
  }

  ngOnChanges(data) {
    if (data.resouces$ && this.resouces$) {
      this.resouces$(this.id, this.type).subscibe(res => {});
    }
  }

}