Bartosz Stępak
Bartosz Stępak

Reputation: 63

Passing Observable to another component in Angular

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"

Upvotes: 0

Views: 7146

Answers (3)

Vlad274
Vlad274

Reputation: 6844

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);
    })
}

Upvotes: 2

Julian W.
Julian W.

Reputation: 1571

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 => {});
    }
  }

}

Upvotes: 0

Avin Kavish
Avin Kavish

Reputation: 8937

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

Upvotes: 2

Related Questions