Home > other >  How to do conditionally something in rxjs pipe?
How to do conditionally something in rxjs pipe?

Time:11-24

Could somebody tell me what is the right syntax for an rxjs pipe with a conditional operation? In this case i would like to do the mapping with the filter, if the enviroment name array lenght is not 1. How can i use an if statement without return? Is there any rxjs operator for this?

environmentName = ['env1', 'env2'];

sourceList$ = this.getSources().pipe(
tap((srcList) => console.log(srcList)), //[["stylesheet","env1-xyz"],["include","cable"],...]
// if(this.environmentName.length!==1){
map((sourceList) => sourceList.filter((scr) => scr[1].startsWith(this.environmentName[0]) || scr[0] === 'include')),
//}
repeatWhen(() => this.sourceListChanged$)
);

CodePudding user response:

Could somebody tell me what is the right syntax for an rxjs pipe with a conditional operation?

If client software is already piping from a source, filter is a tool that provides a quick solution. Returning true from filter will continue the pipe. Returning false will drop the value from the pipe. Returning false does not affect the underlying subscription.

const source$ = /* snip */;
source$.pipe(
  filter((v) => v % 2 === 0) // non-even values do not continue
  tap((v) => {
    console.log("Even value received: ", v);
  })
).subscribe(
  /* snip */
)

If a new source is desired, then iif is suitable.

iif(
  () => someCondition, // if someCondition
  () => sourceA$, // then return sourceA
  () => sourceB$, // else return sourceB
).pipe(
  /* pipe the source returned from `iif` */
).subscribe(
  /* subscribe to the source returned from `iif` */
)

Based on your example, the condition you want to check is whether an array has a length of 1 (false) or not (true).

if the enviroment name array lenght is not 1

I've adapted your code on CodePen to make sense as a standalone example, here is an example:

const environmentName = ['env1', 'env2'];
sourceList$.pipe(
  tap((sourceList) => console.log("Source list: ", sourceList)),
  filter(() => environmentName.length !== 1)
).subscribe(
  /* snip */
);

Your code fails because you are performing the opposite check. In your example, the pipe will continue only if the length IS 1. Since the array is hard-coded and has a length of 2, the filter will never pass.

CodePudding user response:

Mentioned iif is not operator. Use e.g. mergeMap to incorporate it into your code:

environmentName = ['env1', 'env2'];

const filterSourceListByEnv1OrInclude = srcList => srcList.filter((scr) => scr[1].startsWith(this.environmentName[0]) || scr[0] === 'include');

sourceList$ = this.getSources().pipe(
  tap((srcList) => console.log(srcList)),
  mergeMap(srcList => iff(
    () => this.environmentName.length !== 1,
    of(filterSourceListByEnv1OrInclude(srcList)),
    of(srcList)
  )),
  repeatWhen(() => this.sourceListChanged$)
);

Or ternary operator could be used instead of iif:

sourceList$ = this.getSources().pipe(
  tap((srcList) => console.log(srcList)),
  mergeMap(srcList => of(this.environmentName.length !== 1
    ? filterSourceListByEnv1OrInclude(srcList)
    : srcList
  )),
  repeatWhen(() => this.sourceListChanged$)
);
  • Related