1

Could someone please give me a working example (or refer me to one) which illustrates this functionality in Angular:

Component A: gets data from a server (A user enters a word in an input field, the server responds with some definition)

Component B: the data received from the server will be displayed in this component.

I, for some reason, cannot get the data to display in another component than the one that fetched it from the server.

For more details: I posted the question here: Angular: How to redirect into another page upon submit

I have a service to share the data between components, but my problem is how do I pass the data received from the server from Component A to Component B?

omar
  • 401
  • 1
  • 7
  • 26
  • 2
    Take a look at the Angular documentation about component interaction https://angular.io/guide/component-interaction#component-interaction. If the components have a parent/child relationship, @Input() and @Output() can be used. If the components have a sibling relationship (they are in the same parent component), a service can be used to pass data between them. The documentation has examples of both methods. – josavish Apr 14 '19 at 23:25
  • I know I'm using a service: my question is how do I concretely pass the data from component A to component B and at the same time display the data in component B? I guess it's a sibling relationship here. – omar Apr 15 '19 at 04:45
  • omar have you used EventEmitter before this?? – Syed Kashif Apr 15 '19 at 06:00
  • Kashif, no I haven't used EventEmitter before but I'm going to follow the tutorial to get the basics. – omar Apr 15 '19 at 17:27

3 Answers3

3

From the Angular documentation, data can be shared between components by using:

The third example from the documentation shows communication between parent and child so here is an example of two sibling components sharing data via a service. Stackblitz Example

First, set up the service with a BehaviorSubject. This allows components to push data to and get data from the service.

data.service.ts

import { Injectable } from '@angular/core';
import {of, BehaviorSubject, Observable} from 'rxjs'

@Injectable()
export class DataService {
  private _data: BehaviorSubject<any> = new BehaviorSubject<any>(null)

  constructor() { }

  getData(): Observable<any> {
    return this._data.asObservable();
  }

  setData(data: any) {
    this._data.next(data);
  }

  getSomeData() {
    return of([
      {id: 1, name: 'Name 1'},
      {id: 2, name: 'Name 2'},
      {id: 3, name: 'Name 3'},
    ]);
  }

}

Next create a component, in this case first.component, that has the DataService injected into it. This component uses both methods of communication, EventEmitters with @Output()s and setting data on the service for other components to subscribe to.

first.component.ts

import { Component, EventEmitter, OnInit, Output } from '@angular/core';

import {DataService} from '../data.service';

@Component({
  selector: 'app-first',
  templateUrl: './first.component.html',
  styleUrls: ['./first.component.css']
})
export class FirstComponent implements OnInit {
  @Output() dataLoaded: EventEmitter<any> = new EventEmitter<any>();

  constructor(private dataService: DataService) { }

  ngOnInit() {
    this.dataService.getSomeData().subscribe(
      (data: any) => {
        // use this to emit data to a parent component
        this.dataLoaded.emit(data);

        // use this to set data in the service that other components can subscribe to
        this.dataService.setData(data);
      }
    );
  }

}

In the AppComponent, set up a variable data to hold the data that gets emitted from the FirstComponent.

app.component.ts

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  private _data: any[] = [];

  get data(): any[] {
    return this._data;
  }

  set data(data: any[]) {
    this._data = data;
  }
}

Then listen for the dataLoaded event in the app component template and set the app component's data.

app.component.html

<app-first (dataLoaded)="data = $event"></app-first>

To get data to the SecondComponent, when the FirstComponent subscribes to data and emits it to its parent component, the FirstComponent can also send that data back to the service which puts the data into another Observable that the SecondComponent can subscribe to.

second.component.ts

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

import {DataService} from '../data.service';

@Component({
  selector: 'app-second',
  templateUrl: './second.component.html',
  styleUrls: ['./second.component.css']
})
export class SecondComponent implements OnInit {
  data: any[] = [];

  constructor(private dataService: DataService) { }

  ngOnInit() {
    this.dataService.getData().subscribe(
      (data: any) => this.data = data
    );
  }

}

The SecondComponent can now use the data loaded from the FirstComponent in its template.

second.component.html

<table>
  <thead>
    <tr>
      <th>Id</th>
      <th>Name</th>
    </tr>
  </thead>

  <tbody>
    <tr *ngFor="let item of data">
      <td >{{ item?.id }}</td>
      <td >{{ item?.name }}</td>
    </tr>
  </tbody>
</table>
josavish
  • 461
  • 1
  • 4
  • 9
  • Hi josavish, I will implement your solution and let you know of the results. Thanks! – omar Apr 15 '19 at 17:41
1

Try this

import module.

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

make an object

  @Output() arrayList = new EventEmitter();

emit your data from your first component

this.arrayList.emit(yourdata);

you need to write this line in other component of html file on top (second component)

</app-header (arrayList)='displayChanges($event)'></app-header>

now make your function in secound component where you want to recieved yor data this function call automatically when data emit from first component

displayChanges($firstComponentData){
  var yourData= firstComponentData;
  //your code
}
rajpoot rehan
  • 435
  • 5
  • 14
Syed Kashif
  • 420
  • 6
  • 13
0

This are what services are for.

Services get instantiate one time and are never removed. When you insert them into an component via dependency injection you get always the same instance.

Think of it like a singleton. You can save the data in a variable inside the service. Component A and B can access it and you are sure of that the accessed data are the same in both components.

lynxSven
  • 555
  • 1
  • 10
  • 27