0

I have two different components

first.component.ts

   ngOnInit(): void {
  }
 
  setStatusOfUser(){
    this.Service.setStatus(Id,userId).subscribe((data)=>{
      this.msg=data;
    })
   
  }

second.component.ts

  ngOnInit():void {
    this.getProgress()
  }
  getProgress(){
    this.service1.getProgress().subscribe(data=>{
      this.progresss=data;
      
    });
 
   }

when I am refrshing the page its working but when clicking on the setStatusofUser I want to render the get progress method in another component how to do that.

3 Answers3

0

first.component.ts

You can use ViewChild Annotation to call a method in another component

@ViewChild(SecondComponent) secondComponent!: SecondComponent;

setStatusOfUser(){
this.secondComponent.getProgress();
}
0

The reason why it works only on refresh because you call getProgress() only once onInit(). One possible solution that you can use is to use a service to share info between components.

Service

  private statusObs = new BehaviorSubject<any>(null);

  setStatus(data: any) {
    this.statusObs.next(data);
  }
  
  getStatus() {
    return this.statusObs;
  }

First Component

  constructor(private communicationService:<YourServiceName>){}

   ngOnInit(): void {
  }
 
  setStatusOfUser(){
    this.Service.setStatus(Id,userId).subscribe((data)=>{
      this.communicationService.setStatus(data); // Pass data to the service
      this.msg=data;
    });
  }

Second Component

  constructor(private communicationService:<YourServiceName>){}

  ngOnInit():void {
     this.communicationService.getStatus().subscribe( status => {
        // We used BehaviorSubject<any>(null) with initial value null
        // so use this null check to avoid calling getProcess() in the beggining
        if (status !== null) { // check if your data is the data you want
          this.getProgress();
        }
     });
  }

  getProgress(){
    this.service1.getProgress().subscribe(data=>{
      this.progresss=data;
    });
 
   }
tufonas
  • 303
  • 1
  • 7
0

In your second component...

readonly progress$: Service1['getProgress'];

constructor(
  readonly communicationService: CommunicationService,
  readonly service1: Service1
) {
  this.progress$ = this.communicationService.getStatus().pipe(
    filter(status => status !== null),
    switchMap(() => this.service1.getProgress()), // ignore whatever the status is, just get the new progress.
  );
}

This will create an observable that, each time the observable from getStatus emits, will call this.service1.getProgress() and emit whatever that observable returns... until and unless the observable returned by getStatus emits again.

Then, in your second component's template, to show it:

<div>{{progress$ | asynch}}</div>

This will automatically subscribe, update the web page whenever progress$ emits, and unsubscribe when the component closes.

JSmart523
  • 2,069
  • 1
  • 7
  • 17
  • If `progress$` emits a complex data structure, change it to also pipe a `share` or `shareReplay` operator so that multiple observables that read from `progress$` will share instead of duplicate what is done inside of `progress$`, and have each thing you want to expose on your web page as separate observables. E.g. `this.percentComplete$ = progress$.pipe(map({percentComplete} => percentComplete))` – JSmart523 Jan 22 '22 at 22:48