Conduits provide a simple way of allowing multiple components to share data and remain in sync with minimal setup. It also provides simple control mechanisms to define how data is shared between components through zones.

Creating a Conduit

A conduit is built on top of the RxJS Subject. To create a conduit you should create a public instance variable on your component class. This should be initialized as a new Subject or BehaviorSubject if you want to specify a default value.

When a conduit is created, for example when a component is initialized, it will check if there are any other conduits with the same id in accessible zones and if so will retrieve the latest value. This is useful in scenarios such as a customizable dashboard where widgets may be dynamically added or removed. When a dashboard widget is added it can automatically detect a value to consume from any other widgets with a matching conduit.

The variable should be given the @Conduit decorator with the appropriate configuration. Additionally the component class should extend ConduitComponent where possible to setup all conduits automatically. If it is not possible to extend this class, inject the ConduitZone service and in the ngOnInit hook call zone.registerConduits(this). In the ngOnDestroy hook call zone.unregisterConduits(this) to remove conduits when they are no longer needed.

Below is an example of creating a conduit:

The following properties can be given to the Conduit decorator:

This is an identifier that is used to sync conduits across components. Any conduits with the same id will be kept in sync if they accept input. This can be used to limit when this conduit gets updated. If this property is set to false then it will not update when other conduits with the same id change. If this property is set to true then it will always update when other conduits with the same id change. Alternatively this can be set to a string array of zone ids. If a conduit with the same id changes in one of the specified zones then it will update, otherwise it will not. This can be used to prevent the conduit having an effect on any other. If this property is set to false then it will not emit this change to any other conduit. If this property is set to true then it will emit this change to other conduits. By default when a conduit emits an update, it first performs an equality check to see if the value has actually changed. By default the equality check is a === comparison, however if the conduit value is an object or an array you may need to provide a custom equality check to ensure equality check is efficient and to prevent any infinite loops. The value should be a simple function that receives two arguments, the new value and old value. The function should return true if the object are the same and false if it has changed. It may be desirable to extract or transform the conduit value when it changes. For example, we may have a User conduit that contains an object. In one component we may want only to receive the name of the user. We can use this property to provide a function that takes in the conduit value and returns it in a format we require.

Conduit Utilities

By having our component extend the ConduitComponent we gain access to some utility functions that can be used to create and modify conduits dynamically at runtime.

The following methods are available:

This allows programmatic creation of a conduit at runtime. The function should be called with two parameters, the first is the Subject or BehaviorSubject, and the second is the properties object which is identical to the object normally passed to the @Conduit decorator.

Note: If your class does not extend ConduitComponent, these functions are also available on the ConduitZone service.

This allows conduit properties to be modified at any time. For example, you may wish to alter which zones a Conduit can accept data from. This function should be given two arguments. The first argument should be the Subject or BehaviorSubject, the second should be an object containing the properties you wish to update.

Note: If your class does not extend ConduitComponent, these functions are also available on the ConduitZone service.

Conduit Zones

A conduit zone is a way of easily scoping what conduits can be effected when values change.

To create a conduit zone a component should register the ConduitZone provider and where possible extend the ConduitZoneComponent class. The ConduitZoneComponent class extends ConduitComponent so you also have access to the methods listed above. Each zone must also have a unique id which should be set by adding a zoneId property to the class.

If a class extends ConduitZoneComponent and uses the ngOnInit or ngOnDestroy lifecycle hook, you must call super.ngOnInit() and super.ngOnDestroy from within the respective hook.

If it is not possible to extend the ConduitZoneComponent class, you should inject the ConduitZone service and call the setZoneId function passing it the unique zone id.

Below is an example of how to create a zone:

Conduit zones work with Angular's Injector, so a conduit created in the component, or a child component will be part of that zone. Zones may be nested, so a child component may create a new zone.

The following code can be used to create the example above: