0

I am trying to send data between two unrelated components. I am trying to utilize Event Emitter Output and Address Service.

How to get the first Address Dropdown Event Emitter, to Pass Data to the Service? The service can then send data to the Receiver.

export class AddressDropdownComponent implements OnInit {

  addresses: any[] = [];
  @Input() addressDefaultItem: AddressDto;
  @Input() selectedAddress: any;
  @Input() TxtField: string = 'addressDescription';
  @Output() selectedItemOutput = new EventEmitter();

  constructor(private addressService:AddressServiceProxy ) { }

  ngOnInit() {
  }

  statusSelectedItemChanged(e) {
    this.selectedAddress = e;
  }

Still Working on This Address Service

export class AddressService {

  private messageSource = new BehaviorSubject("default message");
  currentMessage = this.messageSource.asObservable();

  constructor() { }

  changeMessage(message: string) {
    this.messageSource.next(message)
  }

}

Resource: following is only for parent-child, looking for unrelated 'grandfather' or 'sibling' cases

What is the best way to use nested components in Angular 4 and calling a method of a parent to child and vice versa?

3
  • 2
    Possible duplicate of How pass a event from deep nested child to parent in Angular 2? Commented Nov 3, 2019 at 7:46
  • It's such kind of situations when you need to connect components which are not in parent-child relationship it's better to use services. Commented Nov 3, 2019 at 8:48
  • hi @Sergey thats what I am trying to do in question, thanks Commented Nov 3, 2019 at 8:49

1 Answer 1

0

So you have a source let's say ComponentA and some component on top of it several levels let's say ComponentV.

To connect them you need first to connect them via a service. If there is only one instance of each of them you can use a singletone service (has providedIn: 'root' in @Injectable decorator). However, if you can have multiple ComponentV which contain ComponentA you need to provide this service at top-level of hierarchy. In this case ComponentV must have providers: [SomeService] to create a new service instance when ComponentV is created.

Then you define some prop in SomeService to share data.

For example you end up with

// SomeService contents
...
// create a source
private dataSource$ = new Subject();
// Expose as observable so it's value can be changed
// only via exposed method (dataChanged)
data$ = this.dataSource$.asObservable();

// public API to pass new data
dataChanged(data) {
  this.dataSource$.next(data);
}
...

Then you inject this service in ComponentA and define a function to emit data change.

// ComponentA contents
...
constructor(private readonly someService: SomeService) {}

onDataChange(data) {
  // here we notify about data change
  this.someService.dataChanged(data);
}
...

Then you need to subscribe to the observable in top level component

// CompoentV contents
...
constructor(private readonly someService: SomeService) {
  // here we subsribe to changes and use whatever handler we need
  this.someService.data$.subscribe(data => {
    // some logic goes here or pass this data to a method
  });
}
...

This allows one to share some state or events between unrelated or loosely related components.

Sign up to request clarification or add additional context in comments.

2 Comments

hi Sergey, this is helpful, see I have a Kendo dropdown component which uses their event, telerik.com/kendo-angular-ui/components/dropdowns/dropdownlist , I am trying to pass this event into a service , not sure of the syntax or what to write, but $event is embedded in Kendo dropdown
@SailorLuvBoat Event in angular component's relationship is simply (event)="handler($event)" you define some method in component and there you invoke the service's method to populate data. Or you can make your service public and call service's method directly from template like (event)="someService.dataChanged($event)"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.