H. Trujillo
H. Trujillo

Reputation: 437

Angular 2 parent to child communication through service

I have an Angular 2 Application with the following structure

app (dir)
|-parent(dir)
 -parent.component
 -global.service (used to communicate with children)
    |-child1 (dir)
     -child1.component
    |-child2 (dir)
     -child2.component

Such that the app directory contains the parent directory, and the parent directory contains its component, service and a child directory.

And I am trying to implement the Mission service example from Angular.io: Parent and children communicate via a service

Service

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';

@Injectable()
export class GlobalService {


// Observable string sources
private missionAnnouncedSource = new Subject<string>();
private missionConfirmedSource = new Subject<string>();
// Observable string streams
missionAnnounced$ = this.missionAnnouncedSource.asObservable();
missionConfirmed$ = this.missionConfirmedSource.asObservable();
// Service message commands
announceMission(mission: string) {
    this.missionAnnouncedSource.next(mission);
}
confirmMission(astronaut: string) {
    this.missionConfirmedSource.next(astronaut);
}
}

Parent

 @Component({
 selector: 'parent',
 templateUrl: './app/parent/parent.component.html',
 styleUrls: ['./app/parent/parent.component.css'],
 providers: [GlobalService]
 })
export class ParentComponent {
constructor(private globalService: GlobalService) {
globalService.missionConfirmed$.subscribe(
  astronaut => {
    console.log('filter ' + astronaut);
  },
  (error: string) => {
    console.log('filter error')
  },
  () => {
    console.log('filter done fetching')
  });
}
}

Child 1

@Component({
selector: 'child1',
templateUrl: './app/parent/child1/child1.component.html',
styleUrls: ['./app/parent/child1/child1.component.css'],
providers: [GlobalService]
}) 
export class ChildComponent {
filterFormSubmit(filterFormValue: JSON): void {
this.filterFormValue = filterFormValue;
this.globalService.confirmMission('Mars')
}
}

When the child method triggers, know the service receives 'Mars' when I do a console.log(mission), but I cant get the parent to print Mars.

And I'm wondering if its because I have the child in a sub-directory.

Thank you for your time!

Upvotes: 1

Views: 1155

Answers (2)

eko
eko

Reputation: 40647

You need to provide

providers: [GlobalService]

inside a module that is enclosing these components (or in a component which is a parent of both these components). Otherwise the services will be singletons.

Upvotes: 4

Michael
Michael

Reputation: 368

One way you can go is to have @Output() declarations in children that emit an object when data needs to be passed. I think you are saying this is what you are doing, which would get messy pretty quickly.

If you want to use a service, create an object that stores all of the values and add that to your service class. Then, create getters/setters in the service and have the children use those. This stackoverflow shows some examples.

Upvotes: 0

Related Questions