Angular 4 data transfers between 2 unrelated components

I have questions about transferring data to Angular.

Firstly, I don't have a structure like <parent><child [data]=parent.data></child></parent>

My structure

 <container> <navbar> <summary></summary> <child-summary><child-summary> </navbar> <content></content> </container> 

So, in <summary/> I have a selection that sends the value to <child-summary/> and <content/> .

The OnSelect method starts well with (change) inside the <summary/> component.

So, I tried with @Input , @Output and @EventEmitter , but I don’t see how to extract the event as an @Input component, unless I switch to the parent / child template. All the examples that I founded are related between the components.

EDIT: The example with BehaviorSubject does not work (all connected services to the API work well, only the observable starts at startup, but not when the choice matters has changed)

shared service = company.service.ts (used to get company data)

 import { Injectable } from '@angular/core'; import { Headers, Http, Response } from '@angular/http'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/toPromise'; @Injectable() export class SrvCompany { private accountsNumber = new BehaviorSubject<string[]>([]); currentAccountsNumber = this.accountsNumber.asObservable(); changeMessage(accountsNumber: string[]) { this.accountsNumber.next(accountsNumber); } private _companyUrl = 'api/tiers/'; constructor(private http: Http) { } getSociete(): Promise<Response> { let url = this._companyUrl; return this.http.get(url).toPromise(); } } 

invoice.component.ts ("child")

 import { Component, OnInit, Input } from '@angular/core'; import { Headers, Http, Response } from '@angular/http'; import { SrvInvoice } from './invoice.service'; import { SrvCompany } from '../company/company.service'; @Component({ selector: 'invoice', templateUrl: 'tsScripts/invoice/invoice.html', providers: [SrvInvoice, SrvCompany] }) export class InvoiceComponent implements OnInit { invoice: any; constructor(private srvInvoice: SrvInvoice, private srvCompany: SrvCompany) { } ngOnInit(): void { //this.getInvoice("F001"); // Invoice data is linked to accounts number from company. this.srvCompany.currentAccountsNumber.subscribe(accountsNumber => { console.log(accountsNumber); if (accountsNumber.length > 0) { this.srvInvoice.getInvoice(accountsNumber).then(data => this.invoice = data.json()); } }); } //getInvoice(id: any) { // this.srvInvoice.getInvoice(id).then(data => this.invoice = data.json()); //} } 

company.component.ts (parent trigger)

 import { Component, Inject, OnInit, Input } from '@angular/core'; import { Headers, Http, Response } from '@angular/http'; import { SrvCompany } from './company.service'; @Component({ selector: 'company', templateUrl: 'tsScripts/company/company.html', providers: [SrvCompany] }) export class CompanyComponent implements OnInit { societes: any[]; soc: Response[]; // debug purpose selectedSociete: any; ville: any; ref: any; cp: any; accountNumber: any[]; constructor(private srvSociete: SrvCompany) { } ngOnInit(): void { this.getSocietes(); } getSocietes(): void { this.srvSociete.getSociete() .then(data => this.societes = data.json()) .then(data => this.selectItem(this.societes[0].Id)); } selectItem(value: any) { this.selectedSociete = this.societes.filter((item: any) => item.Id === value)[0]; this.cp = this.selectedSociete.CodePostal; this.ville = this.selectedSociete.Ville; this.ref = this.selectedSociete.Id; this.accountNumber = this.selectedSociete.Accounts; console.log(this.accountNumber); this.srvSociete.changeMessage(this.accountNumber); } } 
+25
javascript angular typescript
source share
4 answers

This is the case when you want to use a common service, as your components are structured like brothers and sisters and grandchildren. Here is an example from the video, I created a video about sharing data between components , which solves this exact problem.

Start by creating a BehaviorSubject in a service

 import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; @Injectable() export class DataService { private messageSource = new BehaviorSubject("default message"); currentMessage = this.messageSource.asObservable(); constructor() { } changeMessage(message: string) { this.messageSource.next(message) } } 

Then enter this service into each component and subscribe to the observable.

 import { Component, OnInit } from '@angular/core'; import { DataService } from "../data.service"; @Component({ selector: 'app-parent', template: ` {{message}} `, styleUrls: ['./sibling.component.css'] }) export class ParentComponent implements OnInit { message:string; constructor(private data: DataService) { } ngOnInit() { this.data.currentMessage.subscribe(message => this.message = message) } } 

You can change the value from any of the components and the value will be updated even if you do not have a parent / child relationship.

 import { Component, OnInit } from '@angular/core'; import { DataService } from "../data.service"; @Component({ selector: 'app-sibling', template: ` {{message}} <button (click)="newMessage()">New Message</button> `, styleUrls: ['./sibling.component.css'] }) export class SiblingComponent implements OnInit { message:string; constructor(private data: DataService) { } ngOnInit() { this.data.currentMessage.subscribe(message => this.message = message) } newMessage() { this.data.changeMessage("Hello from Sibling") } } 
+67
source share

if the component is not related to the fact that you need to use the Service

https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service

0
source share

There are two solutions for this.

  • This can be done through a common service using the observable function.

  • You can use ngrx / store for this. It looks like a Redux arch. You will receive data from the state.

0
source share

Here is the simplest example of sharing data between two independent components using an event generator and a service.

fooobar.com/questions/6685968 / ...

0
source share

All Articles