With custom components

Example of a way to link a component custom element to an RxJS state
profile photo
Téo Montlouis
javascript
class Component extends HTMLElement createComponentStore(this)
javascript
import { BehaviorSubject, tap } from "rxjs"; export class Component extends HTMLElement { shadow = this.attachShadow({ mode: "open" }); _store = createStore(null) _observedAttributes$ = new BehaviorSubject(null); connectedCallback() { this._observedAttributes$.next( this.constructor.observedAttributes ?.map(attr => ({ [attr]: this.getAttribute(attr) })) .reduce((prev, curr) => ({ ...prev, ...curr }), {}) ); this._renderSubscription = this._store.subscribe(this.render); } disconnectedCallback() { // shoould we destroy store reducers ? this._renderSubscription?.unsubscribe(); } attributeChangedCallback(name, oldValue, newValue) { const newObservedAttributes = { ...this._observedAttributes$.value, ...{ [name]: newValue } }; this._observedAttributes$.next(newObservedAttributes); } templateStyle(state) { return ""; } template(state) { return ""; } render(state) { this.shadow.innerHTML = ` ${this.templateStyle(state)} ${this.template(state)} `; } // START - ADDED CODE rootState$() { const parentOrHost = el => el.parentNode ?? el.host; let parent = parentOrHost(this); while (parent) { if (parent.isRootState) { return parent.state$; } parent = parentOrHost(parent); } } // END - ADDED CODE set state$(state$) { this._stateSubscription?.unsubscribe(); this._stateSubscription = state$.subscribe(this._state$); } get state$() { return this._state$; } get observedAttributes$() { return this._observedAttributes$; } }
component.js
Related posts
post image
Concrete example of a product card implemented with Potions framework
post image
Creating a new query language specialized in event processing
post image
The actor model - trick to never complete the channel
Powered by Notaku