简体   繁体   中英

Making ajax call from a component to a service and access response from another component

I am learning Angular2 by creating an example where I want to have a button click on Component1 that makes an ajax call to a Service and the response of the ajax should be used and displayed in another component.

在此处输入图片说明

I am able to create the Component1 and able to get the response by making ajax call in Service class. Now how can I display the result in another component

This is my first component:

import { Component } from '@angular/core';
import { ProfileService } from '../shared/index';

@Component({
  selector: 'home-page',
  template: `
  <div>
    <button (click)="loadUser()">Load profile</button>
    {{ profile | json }}
  </div>
  `
})
export class ProfileComponent {
  constructor(private profileService: ProfileService) {}
  profile = {};

  loadUser() {
    this.profileService.getUser().subscribe(data => this.profile = data);
  }
}

This is my service class:

import { Injectable } from '@angular/core';
import { HttpClient, Response } from '@angular/common/http';
import 'rxjs/add/operator/map';

@Injectable()
export class ProfileService {
  constructor (
    private http: HttpClient
  ) {}

  getUser() {
   return this.http.get(`https://conduit.productionready.io/api/profiles/eric`)
    .map(res => res );
  }

}

This is my second component where I want to see the result:

import { Component } from '@angular/core';

@Component({
  selector: 'result-page',
  template: `
  <div>Result Page :     
    {{ profile | json }}
  </div>
  `
})
export class ResultComponent {
  constructor(private profileService: ProfileService) {}
  profile = {};
  username = "";
  bio = "";
}

Basically the ajax response is a Json content, I want to store whole json in profile file. This json contains fields for username and bio, I want to store them in my variables username and bio of my result component.

I am stuck how to build my result component, can you please help me.

I am want to communicate between components, don't want to use any routers here.

The json response is :

{
"profile": {
"username": "eric",
"bio": "Cofounder of Thinkster.io, kinda looks like Peeta from the Hunger Games",
"image": "http://i.imgur.com/S66L2XZ.jpg",
"following": false
}
}

Edit: If the component you are trying to pass the data to is the child of that component you can use the @Input decorator to pass the data to it. The @Input will automatically register the changes and update the template. If you need to do any update functions when this input changes you can use ngOnChanges, but if you are simple displaying the changes you can just use the @Input and it will update the view accordingly.

If the two components are both children of a shared parent you can use the @Ouput decorator on the component1 to output the data to the parent and set the variable that is being passed into the Input of the other.

in results component

export class ResultComponent implements OnChanges {
  @Input results: any;

  constructor(private profileService: ProfileService) {}

  ngOnChanges(changes: SimpleChanges) {
    if(changes['profile'] && changes['profile'].currentValue){
       // do any update functions here if needed
    }
  }
  profile = {};
  username = "";
  bio = "";
} 

and in the profile template

<results-page [profile]="profile"></results-page>

in component1 if that component is also a child

export class ProfileComponent {

  @Ouput() emitProfile = new EventEmitter<any>()

  constructor(private profileService: ProfileService) {}
  profile = {};

  loadUser() {
    this.profileService.getUser().subscribe(data => this.profile = data);
  }
}

and then in the parent you would handle the data emit like so:

handleEmitProfile(profile) { this.profile = profile }

option 2 - add another function in the service.

@Injectable()
export class ProfileService {
  constructor (
    private http: HttpClient
  ) {}

  private profile$ = new Subject();

  getUser() {
    return this.http.get(`https://conduit.productionready.io/api/profiles/eric`)    .map(res => res );
  }

  returnProfile() {
     return this.profile$;
  }

  updateProfileObject(event) {
    this.profile$.next(event);
  }
}

in your results component add this:

this.profileService.returnProfile().subscribe(event => this.profile = event}

and in your profile component

this.profileService.updateProfileObject(this.profile);

and that function will update the profile$ variable in the service calling the function in the results component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM