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$)
);