13

Based on the parameters of the function I want to build the forkJoin() method.

For example:

  • if parameter1 is empty => don't put a http request for it inside the forkJoin()
  • if parameter2 is empty => don't put a http request for it inside the forkJoin()

Code:

getAllByIds(parameter1: any, parameter2: any) {

    let itemList = new Array();

    return Observable.forkJoin(
         this.http.get('rest/fillin/ids/' + parameter1) // don't put this request for parameter1 if it is empty
         .map((res: Response) => res.json()),

         this.http.get('rest/textitem/ids/' + parameter2) // don't put this request for parameter2 if it is empty
         .map((res:Response) => res.json())
    ).map(
        data => {
            itemList.push(data[0]);
            itemList.push(data[1]);
            return itemList;
         }
     );
}

So, is it possible to build up the forkJoin() like this?

Korki Korkig
  • 2,736
  • 9
  • 34
  • 51

1 Answers1

24

Actually this depends on what do you expect to get when you skip some HTTP requests.

Should the output from forkJoin() contain null values or just ignore it completely?

function mockHTTPRequest(id) {
  return Observable.of(id).delay(100);
}

let parameter1 = 'a';
let parameter2 = false;

let sources = [];
if (parameter1) {
  sources.push(mockHTTPRequest('rest/fillin/ids/' + parameter1));
}
if (parameter2) {
  sources.push(mockHTTPRequest('rest/textitem/ids/' + parameter2));
}

Observable.forkJoin(...sources)
  .map(data => {
    console.log(data.length);
    return data;
  })
  .subscribe(values => console.log(values));

See live demo: https://jsbin.com/qorulel/5/edit?js,console

This solution just doesn't create source Observables if parameter1 or parameter2 is false. Notice, that console.log(data.length) can be from 0 to 2 depending on parameterX values.

Or you can just create Observable.of(null) instead of the HTTP requests.

function mockHTTPRequest(id) {
  return Observable.of(id).delay(100);
}

let parameter1 = 'a';
let parameter2 = false; 

let sources = [
  parameter1 ? mockHTTPRequest('rest/fillin/ids/' + parameter1) : Observable.of(null),
  parameter2 ? mockHTTPRequest('rest/textitem/ids/' + parameter2) : Observable.of(null)
];

Observable.forkJoin(...sources)
  .map(data => {
    console.log(data.length);
    return data;
  })
  .subscribe(values => console.log(values));

See live demo: https://jsbin.com/caheno/5/edit?js,console

Now the output has always 2 values. Just some of them are null.

martin
  • 93,354
  • 25
  • 191
  • 226
  • I use the first solution. It works fine but when the `sources` array doesn't contain any elements then I get `EXCEPTION: _b is undefined` error. Is it because I don't make any empty checks on the `sources` array? – Korki Korkig Jan 24 '17 at 10:02
  • 1
    An empty array of sources shouldn't be a problem. This is in fact a valid usecase and is tested https://github.com/ReactiveX/rxjs/blob/master/spec/observables/forkJoin-spec.ts#L199. Can you make a jsbin reproducing the problem? – martin Jan 24 '17 at 11:32
  • I'm now sure that it is not releated with the empty request array. I'll look at to other places. Very useful comment;) – Korki Korkig Jan 25 '17 at 17:01
  • How to add a post http request for that sources array. – Manoj Sanjeewa Mar 11 '19 at 06:20