1

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!

Pengyy
  • 37,383
  • 15
  • 83
  • 73
H. Trujillo
  • 427
  • 1
  • 8
  • 21
  • you want one way to pass the data from parent to children correct ??? If yes why is service needed just pass the input to children – mayur May 12 '17 at 12:43
  • yes, but also from the parent to the child, and between siblings. So I need to do bidirectional communication. Currently I've used injection and setters directly from parent to child to manage my communications, but its becoming messy due to the number of methods and values I have to pass between the family. Commuincations: Parent -> Child or Child->Parent or Child->Child – H. Trujillo May 12 '17 at 12:46
  • can you add your `@Component` declarations (all of them) to this question to see how your components are defined? Maybe is something there. – andreim May 12 '17 at 12:49
  • @andreim is that better? – H. Trujillo May 12 '17 at 12:54
  • 1
    @H.Trujillo yes, is what I thought, you need to remove `providers: [GlobalService]` from children and leave it only at the parent level. It has to do with the hierarchical injectors feature. – andreim May 12 '17 at 13:03

2 Answers2

4

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.

eko
  • 39,722
  • 10
  • 72
  • 98
0

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.

Community
  • 1
  • 1
Michael
  • 368
  • 2
  • 8
  • If I understand correctly, what youre saying is what I did and what I'm trying to do. The problem is it isnt working haha – H. Trujillo May 12 '17 at 12:57
  • echonax beat me to it. [The best answer here is the explanation](http://stackoverflow.com/questions/36198785/how-do-i-create-a-singleton-service-in-angular-2) – Michael May 12 '17 at 13:15