1

I want to use Event emitter and subscribe in parent component.

This is my Service Code

@Injectable()
export class RecipeService{
    recipeselected= new EventEmitter<string>() ;
}

This is code, where I have used, event Emitter.

The function onselected is working

@Component({
  selector: 'app-receipie-item',
  templateUrl: './receipie-item.component.html',
  styleUrls: ['./receipie-item.component.css'],
  providers:[RecipeService]
})
export class ReceipieItemComponent implements OnInit {
  @Input() recipe:ReceipieModel ;//custom property
 
  constructor(private recipeservice:RecipeService) { }

  ngOnInit(): void {
  }

  onselected(){
    this.recipeservice.recipeselected.emit("hello");
    // console.log('hello');
  }  

}

This is code, where I have used, subscribe to event.

The problem is it is not working in subscribe.

@Component({
  selector: 'app-receipies',
  templateUrl: './receipies.component.html',
  styleUrls: ['./receipies.component.css'],
  providers:[RecipeService]
})
export class ReceipiesComponent implements OnInit {
  selectedrecipe:ReceipieModel;
  constructor(private recipeservice:RecipeService) { 

  }

  ngOnInit() {
    this.recipeservice.recipeselected.subscribe(
      recipe=>{ 
        console.log(recipe);
      }
    );
  }

  
}

2 Answers2

1

Is there any specific reason to use EventEmitter in the service? EventEmitter is an Angular specific extension of RxJS Subject and are intended to be used with @Output decorator for data sharing b/n sibling components. Subscribers to RxJS Subject would only receive notifications that are emitted after the subscription.

If the components are unrelated, and if you wish to fetch an emission in the future after a value has been pushed to an observable, you're better off using either BehaviorSubject or ReplaySubject.

I'd illustrate using ReplaySubject with buffer 1. It can "hold/buffer" the last emitted value and would emit to the subscribers in the future.

Service

import { Observable, ReplaySubject } from 'rxjs';

@Injectable()
export class RecipeService{
  private recipeSelected: ReplaySubject<string> = new ReplaySubject<string>(1);  // <-- buffer 1
  public recipeSelected$: Observable<string> = this.recipleSelected.asObservable();

  public setSelected(recipe: string): void {
    this.recipleSelected.next(recipe);
  }
}

Component 1 (sender)

onselected(){
  this.recipeservice.setSelected("hello");
}  

Component 2 (recipient)

ngOnInit() {
  this.recipeservice.recipeSelected$.subscribe(
    recipe => { 
      console.log(recipe);
    }
  );
}
ruth
  • 29,535
  • 4
  • 30
  • 57
1

You are mixing up things.

Either use the Service to define an Observable like this:

  private _subject$: Subject<string> = new Subject<string>();

  get subject$(): Subject<string> {
    return this._subject$;
  }

  // emit new data
  this.yourService.subject$.next('new data');

Then, in the component where you want to receive the data:

this.yourService.subject$.subscribe(data => { console.log(data) }

or using EventEmitter

  // componentA.ts
  @Output() public onDataChanged: EventEmitter<Array<EventItem>> = new EventEmitter();

  // publish new data
  public dataChanged() {
    this.onDataChanged.emit('new data')
  }

  // any other component, using your 'app-componentA'
  <app-componentA
      (dataChanged)="receivingMethod($event)">
  </app-componentA>

Here is some literature:

BehaviorSubject vs Observable?

https://angular.io/api/core/EventEmitter

jo-chris
  • 362
  • 6
  • 13