Search code examples
angularrxjs

Why I get undefind data outside of subscribe in angular


I'm using Angular and trying to fetch data, then assign the data to passToChild variable to use it outside subscribe, and pass it to child component, but when I use this variable outside subscribe, I get undefined. I know this because of Subscribe(), will execute asynchronously, so when I try to pass it to child has no data because subscribe hasn't finished yet Is there a way to allow passToChild variable to get data, then pass it?

service

  getData(): Observable<any> {
  const url = "https://jsonplaceholder.typicode.com/posts";
  return this.http.get<any>(url)
  }

component.ts

import { Component, OnInit } from '@angular/core';
import { FetchdataService } from "./services/fetchdata.service"
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent  implements OnInit  {

  passToChild;
  constructor(private Fetchdata: FetchdataService) { }

  ngOnInit(): void {
        this.Fetchdata.getData().subscribe((data) => {
          this.passToChild = data;
          console.log(this.passToChild) // Show all data

        });
        console.log(this.passToChild) //undefined
  }
}

component.html

<app-child [test]="passToChild"></app-child>

Could someone please explain to me how I can use what's inside the subscribe.


Solution

  • Use *ngIf on the app-child so you control component attached or detached, and by using this way you need to catch the returned observable from your serves and unsubscribe it manually

    <app-child *ngIf="passToChild" [test]="passToChild"></app-child>
    

    or you can directly interact with the returned observable from your service

    passToChild$: Observable<any>;
    constructor(private Fetchdata: FetchdataService) {}
    ngOnInit(): void {
        this.passToChild$ = this.Fetchdata.getData();
    }
    

    and in your template use async pipe, using this way you do not need to unsubscribe observable in your hand

    <app-child *ngIf="passToChild$ | async as passToChild" [test]="passToChild"></app-child>