Pass API data from one component into another component?

不打扰是莪最后的温柔 提交于 2019-12-17 13:10:41

问题


I am learning Full-stack Angular4, and wanted to know how would I be able to get data from a get call from one component into another so I can relay the data into the html page with {{data.name}}?

I tried importing the component into the other component, then setting an empty object into that component.data which holds the data, but I get a empty object as a response back.

What am I doing wrong?

UPDATE:

my shared service:

import {Injectable} from "@angular/core";
import {Http, Response, Headers, RequestOptions} from "@angular/http";
import {Observable} from "rxjs/Rx";
import 'rxjs/add/operator/map';

@Injectable()
export class DataService {
    apiData: any;
    constructor(private http: Http) {}

    fetchData() {
        return this.http.get('/api/data').subscribe((data) => {
            this.apiData = data.json();
            console.log(this.apiData);
        })
    }
}

target component:

import { Component } from "@angular/core";
import { AllTablesComponent } from '../tables/alltables.component';
import { DataService } from './../data.service';


@Component({
    selector: 'app-target',
    templateUrl: './target.component.html',
    styleUrls: ['./target.component.css']
})
export class TargetComponent {
    data: any;

    constructor(private dataService: DataService) {

        this.data = this.dataService.fetchData();
        console.log("inside target component");
        console.log(this.data);
    }
}

Screenshot of Empty object from component vs actual data from the data service.


回答1:


First of all, you can see that the console log in component is executed before fetching the data from the backend. This, because this is asynchronous, so it takes a while for the response to arrive.

Second problem, which is related to the same issue, i.e, this being asynchronous, is that you cannot return anything from subscribe, you need to return an Observable to your component and in the component subscribe, either doing it "manually" or then using the async pipe.

If you want to share data to other components after initially getting it another component, what you can do is to use a BehaviorSubject, so declare this in your service:

import {BehaviorSubject} from 'rxjs/BehaviorSubject';

//....

// don't use "any", type your data instead!
private apiData = new BehaviorSubject<any>(null);
public apiData$ = this.apiData.asObservable();

fetchData() {
  return this.http.get('/api/data').map((data) => {
    return data.json();
  })
}

// here we set/change value of the observable
setData(data) { 
  this.apiData.next(data)
}

and in the component where you are fetching the data and want to broadcast to other components, do...

this.dataService.fetchData()
  .subscribe(data => {
    this.data = data;
    // set data in service which is to be shared
    this.dataService.setData(data)
  })

So now we have in this initial component fetched the data, and setting the data in service, which is broadcast to all other components that need it. In those components you just subscribe to this observable.

constructor(private dataService: DataService) { 
  dataService.apiData$.subscribe(data => this.data = data)
}

This solution is based on the idea that you have one component that initially gets the data and then shares it with other components.




回答2:


The Async Pipe is good to go here! You can also wrap it into a ngIf expression and give it an alias. It makes sure that you wont get and "cannot doSomething with null or undefined" in the child.

Something like that:

<div *ngIf="observalbe$ | async as someAlias">
   <app-toBeRenderedWithDataOfObservable [fieldOfChild]="someAlias""></app-toBeRenderedWithDataOfObservable>
</div>


来源:https://stackoverflow.com/questions/47376442/pass-api-data-from-one-component-into-another-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!