Sampath
Sampath

Reputation: 65870

forkJoin is not working without first on Api method

I have written forkJoin as shown below.It is not working (and no errors too) if I'll not set api method as first.Can you tell me why?

my.ts

    let getMyBookMarksApi = this.userService.getMyBookMarks(this.page);//needs first()
    let getMyTopicsApi = this.userService.myTopic();//needs first()

    Observable.forkJoin([getMyBookMarksApi, getMyTopicsApi])
        .subscribe(res => {
            this.setMyProfile(res[0]);
            this.arrangeMyTopics(res[1]);
        },
        error => { },
        () => { });

service.ts

 myTopic() {
 return this.api.get(config.myTopics).map((res: any) => res.json()).first();//without first forkjoin is not working.Why?
 }

api.ts

 get(api) {
        return new Observable(observer => {
            let header = new Headers();
            this.createHeader(header)
                .then(() => {
                    let options = new BaseRequestOptions();
                    options.withCredentials = true;
                    options.headers = header;
                    this.http.get(api, options)
                        .subscribe(response => {
                            observer.next(response);
                        }, (e) => {
                            observer.error(e);
                        });
                })
        })
    }

Api response is just like this:

{
  "num_of_definitions": 11,
  "categories": [
    {
      "id": 68,
      "name": "Founders",
      "num_of_definitions": 1,
      "icon": {
        "large": ""
      },
      "from_color": "#1E3C72",
      "to_color": "#2A5298"
    },
    {
      "id": 27,
      "name": "Innovation",
      "num_of_definitions": 1,
      "icon": {
        "large": ""
      },
      "from_color": "#EE0979",
      "to_color": "#FF6A00"
    },
    {
      "id": 58,
      "name": "Life success",
      "num_of_definitions": 1,
      "icon": {
        "large": ""
      },
      "from_color": "#D53369",
      "to_color": "#CBAD6D"
    },

  ]
}

Upvotes: 1

Views: 1193

Answers (1)

LookForAngular
LookForAngular

Reputation: 1070

Forkjoin works by subscribing to all the observables in parallel, and only when all of them have completed they're joined back. The keyword here is when they complete. The operator .first() takes the first emitted element from an observable and then complete. Probably because your source observables werent completing

Foe the sample to complete add the onComplete line just after the onNext

 get(api) {
    return new Observable(observer => {
        let header = new Headers();
        this.createHeader(header)
            .then(() => {
                let options = new BaseRequestOptions();
                options.withCredentials = true;
                options.headers = header;
                this.http.get(api, options)
                    .subscribe(response => {
                        observer.next(response);
                        // add this line, it should trigger the completion of the outer observable
                        observer.complete();
                    }, (e) => {
                        observer.error(e);
                    });
            })
    })
}

Upvotes: 2

Related Questions