We've all had occasions where we've felt the need to simply pipe a tap(console.log) to our Observables to get some insight into what is occuring at a certain time.
This operator aims to reduce the amount of typing you'll have to do!
Install the package:npm install rxjs-debug-operator
It's super simple to add and use:
Use your prefered import method:
import{debug}from'rxjs-debug-operator';// ORconst{ debug }=require('rxjs-debug-operator');Then pipe it to your Observables:
constobs$=source.pipe(debug());You can add a label to help identify the Observable:
constobs$=source.pipe(debug('My Observable'));// OUTPUT// My Observable {value}It even allows you to turn it off if you are in a production environment, or for any other reason you wouldn't want to log to the console:
constobs$=source.pipe(debug({shouldIgnore: true}));We can use it on its own to simply log out values to the console
constobs$=of('my test value');obs$.pipe(debug()).subscribe();// OUTPUT:// my test valueWe can add a label to the logs:
constobs$=of('my test value');obs$.pipe(debug('Obserable A')).subscribe();// OUTPUT:// Obserable A my test value// We can label it using the config object syntax:constobs$=of('my test value');obs$.pipe(debug({label: 'Obserable A'})).subscribe();// OUTPUT:// Obserable A my test value// However, if we add a label and custom notification handlers,// we will not get the label in the logs by default:constobs$=of('my test value');obs$.pipe(debug({label: 'Obserable A',next: (value)=>console.log(value),})).subscribe();// OUTPUT:// my test valueWe can also set up our own notification handlers if we prefer:
constobs$=of('my test value');obs$.pipe(debug({next: (value)=>console.log('my custom handler:',value)})).subscribe();// OUTPUT:// my custom handler: my test valueconstobs$=throwError('uh oh');obs$.pipe(debug({error: (value)=>console.log('my error handler:',value)})).subscribe();// OUTPUT:// my error handler: uh ohconstobs$=of('my test value');obs$.pipe(debug({complete: (value)=>console.log('I completed')})).subscribe();// OUTPUT:// I completedWe can access the default logger for more flexibility:
constobs$=of('my test value');obs$.pipe(debug((logger)=>({next: (v)=>logger.warn('Warning!',v),}))).subscribe();// OUTPUT// WARN: Warning! my test valueYou can set some globals that make it more convenient to change:
- the default logger
- a global prefix to be appended to all logs
- a global-level ignore flag
You can change the default logger by creating an object that matches the DebugLogger interface, which can be seen below:
exportinterfaceDebugLogger{log: (...args: unknown[])=>void;error: (...args: unknown[])=>void;warn?: (...args: unknown[])=>void;debug?: (...args: unknown[])=>void;info?: (...args: unknown[])=>void;}Once you have created your new logger, you can set it to be used as the default logger using setGlobalDebugConfig()
setGlobalDebugConfig({logger: myNewLogger,});Now all your debug() operators will use your new logger to log the values it receives.
You can also add a string prefix to all your logs at a global level, which can be useful to help identify logs.
setGlobalDebugConfig({prefix: 'My Prefix',});You can also set whether all debug() should not log at the global level. This can be useful for turning it off in production environments.
setGlobalDebugConfig({shouldIgnore: isProduction,});import{DebugLogger,setGlobalDebugConfig}from'rxjs-debug-operator';constwinston=require('winston');constsysLogger=winston.createLogger({level: 'info',format: winston.format.json(),transports: [//// - Write all logs with level `error` and below to `error.log`// - Write all logs with level `info` and below to `combined.log`//newwinston.transports.File({filename: 'error.log',level: 'error'}),newwinston.transports.File({filename: 'combined.log'}),],});constdebugLogger: DebugLogger={log: (v)=>sysLogger.info(v),error: (e)=>sysLogger.error(e),};setGlobalDebugConfig({logger: debugLogger});constobs$=of('my test value');obs$.pipe(debug()).subscribe();// OUTPUT// 'my test value' written to `combined.log`It should be noted that local config options passed to the debug() operator will take precedence over any global values
debug(config?: Partial<DebugOperatorConfig>)
See the list of options available to configure the operator below
| Option | Description | Type | Default |
|---|---|---|---|
shouldIgnore | Do not perform the Debug actions | boolean | false |
label | Add a label to the logs to help identify the Observable | string | null |
next | Action to perform when Observer receives a Next notification | (value: T) => void | console.log |
error | Action to perform when Observer receives an Error notification | (value: unknown) => void | console.error |
complete | Action to perform when Observer receives a Completion notification | () => void | () => null |
setGlobalDebugConfig(config: Partial<GlobalDebugConfig>)
| Option | Description | Type | Default |
|---|---|---|---|
shouldIgnore | Do not perform the Debug actions | boolean | false |
prefix | Add a label to the logs to help identify the Observable | string | null |
logger | Logger to use to log values recieved by debug() | DebugLogger | console |
| Option | Description | Type | Default |
|---|---|---|---|
log | Basic log | (...args: unknown[]) => void | console.log |
error | Error log | (...args: unknown[]) => void | console.error |
info? | Info log | (...args: unknown[]) => void | console.info |
warn? | Warn log | (...args: unknown[]) => void | console.warn |
debug? | Debug log | (...args: unknown[]) => void | console.debug |