Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: RxJS Observables for onChange events #3

Open
manuelpoell opened this issue Oct 11, 2023 · 0 comments
Open

Feature Request: RxJS Observables for onChange events #3

manuelpoell opened this issue Oct 11, 2023 · 0 comments

Comments

@manuelpoell
Copy link

Currently onChange events are handled through callbacks, which is fine for most use-cases. However implementing these functions to return RxJS observables would allow better reactive programming style and usage of the powerful RxJS Operators.

With function overloads you could still provide backwards-compatibility to leave the choice to the extension developer to use either observables or callbacks. With the only downside being RxJS an additional dependency to this SDK.

Here is a code example with observables referencing to the Initiative Tracker extension example:

Using observable instead of callback

import OBR from "@owlbear-rodeo/sdk";

const ID = "com.tutorial.initiative-tracker";

export function setupInitiativeList(element) {
  const renderList = (items) => {
    ...
  };
  OBR.scene.items.onChange().subscribe(renderList);
}

Example with RxJS map-operator

import OBR from "@owlbear-rodeo/sdk";
import { map } from "rxjs/operators";

const ID = "com.tutorial.initiative-tracker";

export function setupInitiativeList(element) {
  const renderList = (items) => {
    // Create new list nodes for each initiative item
    const nodes = [];
    for (const initiativeItem of items) {
      const node = document.createElement("li");
      node.innerHTML = `${initiativeItem.name} (${initiativeItem.initiative})`;
      nodes.push(node);
    }
    element.replaceChildren(...nodes);
  };

  OBR.scene.items.onChange()
    .pipe(
      map((items) => {
        const initiativeItems = [];
        for (const item of items) {
          const metadata = item.metadata[`${ID}/metadata`];
          if (metadata) {
            initiativeItems.push({
              initiative: metadata.initiative,
              name: item.name,
            });
          }
        }
        // Sort so the highest initiative value is on top
        return initiativeItems.sort(
          (a, b) => parseFloat(b.initiative) - parseFloat(a.initiative)
        );
      })
    ).subscribe(renderList);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant