1

I have two services with

ser1.

  getdata1() {
    this.http.get<{message:string,Data1:any}>('http://localhost:3000/api/1')
      .pipe(map((data1)=>{
        return Data1.Data1.map(data=>{
          return  {
            id: data._id,
            data1Title:data1.data1Title,
          }
        })
      })).subscribe((data1) => {
        this.data1=data1
        this.serv1Subject.next([...this.data1])
      })
  }

  getData1Listener() {
    return this.serv1Subject.asObservable()
  }

ser2

  getdata2() {
    this.http.get<{message:string,Data2:any}>('http://localhost:3000/api/2')
      .pipe(map((data2)=>{
        return Data2.Data2.map(data=>{
          return  {
            id: data._id,
            data2Title:data2.data1Title,
          }
        })
      })).subscribe((data2) => {
        this.data2=data2
        this.serv2Subject.next([...this.data2])
      })
  }

  getData2Listener() {
    return this.serv2Subject.asObservable()
  }

Now on componentx i need to fetch the data1 and data2 in nginit and after the data is available need to perform an functionY

How can i use subscribe to trigger an functionY?

In componentx.ts

ngOnInit() {
    this.Service1OberableSubject = this.serv1.getData1Listener().subscribe((data1) => {
      this.data1 = data1;
    })
    this.Service2OberableSubject = this.serv2.getData2Listener().subscribe((data2) => {
      this.data2 = data2;
    })
    this.serv1.getdata1()
    this.serv2.getdata2()
  }
4
  • 1) Are you using the result from the request in another place for which you are using subject? 3) Does function Y require the result of both the api or just need to execute after the completion of two api? Commented Aug 23, 2020 at 15:23
  • @j4rey 1. No those are independent request 2. yes function y requires both return data from services Commented Aug 23, 2020 at 15:28
  • but are you using the response anywhere else other than passing it to function Y? I see you are storing the result in multiple places a) in data variable and b) in Subject. Commented Aug 23, 2020 at 15:31
  • No those services do cater in different componets but i am mapping both in componentX to render all together Commented Aug 23, 2020 at 15:39

4 Answers 4

1

Possibly something like this. Use tap to tap into the response and do anything needed. And forkJoin will merge the response and give it in an array, the first index will the be response of the first observable that was passed in.

getdata1() {
    this.http.get<{message:string,Data1:any}>('http://localhost:3000/api/1').pipe(
        map((data1)=>{
            return Data1.Data1.map(data=>{
              return {
                id: data._id,
                data1Title:data1.data1Title,
              }
            })
        }),
        tap((data1)=>{
            //save to data1 if needed
            this.serv1Subject.next([...this.data1]))
        })
    )
}

getdata2() {
    this.http.get<{message:string,Data2:any}>('http://localhost:3000/api/2').pipe(
        map((data2)=>{
            return Data2.Data2.map(data=>{
                return  {
                    id: data._id,
                    data2Title:data2.data1Title,
                }
            })
        }),
        tap((data2)=>{
            //save to data2 if needed
            this.serv2Subject.next([...this.data2]))
        })
    )
}


forkJoin(
    getdata1(),
    getdata2()
).subscribe((x:any[])=>this.functionY(x));
  
functionY([a, b]){
    console.log({a: a,b: b});
}
Sign up to request clarification or add additional context in comments.

Comments

1

You can use forkJoin from rxjs.

import { forkJoin } from 'rxjs';

component.ts

ngOnInit() {
  forkJoin([this.serv1.getData1Listener(), this.serv2.getData2Listener()]).subscribe(data => {
    this.data1 = data[0];
    this.data2 = data[1];

  });
}

1 Comment

forkJoin will only complete once all its input Observables are completed, what most likely wouldn't happen in this context, since both this.serv1.getData1Listener() and this.serv2.getData2Listener() are Subjects (unless they are unsubscribed_
0

Here's an example of how you can have if implemented:

import { zip } from 'rxjs';
import { first } from 'rxjs/operators';

ngOnInit() {

  this.serv1.getdata1()
  this.serv2.getdata2()

  zip(this.serv1.getData1Listener(), this.serv2.getData2Listener())
  .pipe(first())
  .subscribe(([data1, data2]) => {
     this.data1 = data1;
     this.data2 = data2;

     functionY(data1, data2)
  })

}

7 Comments

After ngOnInit() the next on getData1Listener & getData2Listener doesn't work
both getData1Listener and getData2Listener each has to emit value in order for zip to emit
ok so i have 2 different services after calling function in one service how can i hit next on another service?
I'm not sure what is the issue, In your example this.serv1.getdata1() calls next on the first subject and this.serv2.getdata2() calls next on the second
if i add data on service 1 i will be hitting next on service1 only service2 next will took place when i add data on service2. i want to hit next on other service when i add data to different service
|
0

forkJoin should be the best operator in this scenario. It is equally important to understand other higher order operators, this will help to know when to use those. For e.g.

concatMap — helps to map observables in sequence while waiting for previous observable to complete. The best use case would be a sequential form save.

mergeMap — helps mapping of observables running in parallel. All the previous Observables are kept alive.

switchMap — switchMap is the way to go if we want to cancel previous subscriptions. Type-ahead feature is best implemented using switchMap combined with deboundTime() and distinctUntilChanged().

exhaustMap — used for ignoring newly emitted values till ongoing observable is complete. Best used when we are saving data on click of a button, which has a probability of being clicked multiple times.

1 Comment

how can i use mergeMap here?

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.