Overview
Ignores all items emitted by the source Observable and only passes calls of complete or error.
This operator is useful when you care about when a stream completes or errors, but not about the values it emits. It effectively suppresses all next notifications.
Type Signature
function ignoreElements () : OperatorFunction < unknown , never >
Parameters
This operator takes no parameters .
Returns
OperatorFunction<unknown, never> - A function that returns an empty Observable that only calls complete or error, based on which one is called by the source Observable.
How It Works
Subscribes to the source Observable
Ignores all next notifications (never calls the observer’s next handler)
Forwards complete notification when source completes
Forwards error notification if source errors
Think of ignoreElements as a filter that blocks all values but lets completion and error events through.
Usage Examples
Basic Example: Ignore All Values
import { of , ignoreElements } from 'rxjs' ;
of ( 'you' , 'talking' , 'to' , 'me' )
. pipe ( ignoreElements ())
. subscribe ({
next : word => console . log ( word ),
error : err => console . log ( 'error:' , err ),
complete : () => console . log ( 'the end' ),
});
// Output:
// 'the end'
Wait for Operation to Complete
import { interval , take , ignoreElements , tap } from 'rxjs' ;
const operation$ = interval ( 1000 ). pipe (
take ( 5 ),
tap ( i => console . log ( 'Processing step' , i )),
ignoreElements ()
);
operation$ . subscribe ({
complete : () => console . log ( 'Operation complete!' )
});
// Output:
// Processing step 0
// Processing step 1
// Processing step 2
// Processing step 3
// Processing step 4
// Operation complete!
Track API Call Completion
import { ignoreElements , tap } from 'rxjs' ;
import { ajax } from 'rxjs/ajax' ;
const saveData$ = ajax . post ( '/api/save' , { data: 'important' }). pipe (
tap ( response => console . log ( 'Saved with ID:' , response . id )),
ignoreElements () // Don't need the response downstream
);
saveData$ . subscribe ({
complete : () => {
console . log ( 'Save operation completed' );
showSuccessMessage ();
},
error : err => {
console . error ( 'Save failed:' , err );
showErrorMessage ();
}
});
Loading Indicator
Batch Operations
Side Effect Streams
import { ignoreElements , finalize } from 'rxjs' ;
import { ajax } from 'rxjs/ajax' ;
const spinner = document . querySelector ( '#spinner' ) as HTMLElement ;
function performOperation () {
spinner . style . display = 'block' ;
return ajax . post ( '/api/operation' , { data: 'value' }). pipe (
ignoreElements (),
finalize (() => {
spinner . style . display = 'none' ;
})
);
}
performOperation (). subscribe (
() => {}, // Never called
err => console . error ( 'Operation failed:' , err ),
() => console . log ( 'Operation succeeded' )
);
When to Use
Use ignoreElements when:
You only care about completion or error , not the values
Implementing “wait until done” logic
Tracking operation lifecycle without caring about results
Creating side-effect-only streams with tap
Coordinating multiple operations where values don’t matter
Don’t use ignoreElements when:
You need to access the values emitted by the source
You need to transform values (use map, switchMap, etc.)
You want to conditionally ignore values (use filter instead)
The stream never completes (the operator would never emit anything)
Common Patterns
Wait for Multiple Operations
import { forkJoin , ignoreElements } from 'rxjs' ;
import { ajax } from 'rxjs/ajax' ;
const initialization$ = forkJoin ([
ajax . post ( '/api/init-cache' , {}). pipe ( ignoreElements ()),
ajax . get ( '/api/load-config' ). pipe ( ignoreElements ()),
ajax . post ( '/api/register-session' , {}). pipe ( ignoreElements ())
]);
initialization$ . subscribe (
() => console . log ( 'App initialized' ),
err => console . error ( 'Initialization failed:' , err )
);
Convert to Completion Signal
import { interval , take , ignoreElements , startWith } from 'rxjs' ;
// Wait for timer to complete, then signal
const timer$ = interval ( 1000 ). pipe (
take ( 5 ),
ignoreElements (),
startWith ( 'start' ) // Add a signal value
);
timer$ . subscribe (
value => console . log ( 'Value:' , value ),
err => console . error ( 'Error:' , err ),
() => console . log ( 'Timer completed' )
);
// Output:
// Value: start
// Timer completed (after 5 seconds)
Chain Operations Without Values
import { of , concatMap , ignoreElements , tap } from 'rxjs' ;
import { ajax } from 'rxjs/ajax' ;
const workflow$ = of ( null ). pipe (
concatMap (() =>
ajax . post ( '/api/step1' , {}). pipe (
tap (() => console . log ( 'Step 1 done' )),
ignoreElements ()
)
),
concatMap (() =>
ajax . post ( '/api/step2' , {}). pipe (
tap (() => console . log ( 'Step 2 done' )),
ignoreElements ()
)
),
concatMap (() =>
ajax . post ( '/api/step3' , {}). pipe (
tap (() => console . log ( 'Step 3 done' )),
ignoreElements ()
)
)
);
workflow$ . subscribe (
() => console . log ( 'Workflow complete' )
);
Error Handling with ignoreElements
import { of , ignoreElements , catchError } from 'rxjs' ;
import { ajax } from 'rxjs/ajax' ;
const operation$ = ajax . post ( '/api/risky-operation' , {}). pipe (
ignoreElements (),
catchError ( err => {
console . error ( 'Operation failed:' , err );
// Return empty to complete the stream
return of ( undefined );
})
);
operation$ . subscribe ({
complete : () => console . log ( 'Done (success or handled error)' )
});
Be careful with infinite streams. If your source never completes or errors, ignoreElements will never emit anything, and your subscription will never complete.
Practical Use Cases
Initialization Sequence
import { concat , ignoreElements , tap } from 'rxjs' ;
import { ajax } from 'rxjs/ajax' ;
const initSteps = [
ajax . get ( '/api/auth' ). pipe (
tap ( user => console . log ( 'Authenticated:' , user )),
ignoreElements ()
),
ajax . get ( '/api/config' ). pipe (
tap ( config => console . log ( 'Config loaded:' , config )),
ignoreElements ()
),
ajax . post ( '/api/track-session' , {}). pipe (
ignoreElements ()
)
];
concat ( ... initSteps ). subscribe ({
complete : () => {
console . log ( 'Initialization complete' );
startApp ();
},
error : err => {
console . error ( 'Initialization failed:' , err );
showError ();
}
});
Progress Tracking
import { interval , take , ignoreElements , tap , scan } from 'rxjs' ;
const progress$ = interval ( 100 ). pipe (
take ( 20 ),
scan (( acc ) => acc + 5 , 0 ),
tap ( percent => updateProgressBar ( percent )),
ignoreElements ()
);
progress$ . subscribe ({
complete : () => console . log ( 'Progress complete' )
});
function updateProgressBar ( percent : number ) {
console . log ( `Progress: ${ percent } %` );
}
Combine ignoreElements with tap to create side-effect-only streams that signal completion without propagating values.
TypeScript Note
The return type of ignoreElements is OperatorFunction<unknown, never>, meaning:
It accepts any input type (unknown)
It never emits any values (never)
It only completes or errors
This makes it type-safe since you cannot accidentally try to use values that will never exist.
filter - Conditionally pass values through
take - Take first N values then complete
skip - Skip first N values
tap - Perform side effects (often combined with ignoreElements)
finalize - Run logic on completion or error