Subscribing to Queries

Subscribing to a query lets you receive updates to that query. This is a powerful tool for collaborative apps. It's also just as easy as making a regular entity query.

Before we get started, you can follow the PubSub Server Package page to set up a Nymph PubSub server.

You can use the subscribeEntities method on PubSub to subscribe to a query. It will return a function you can call to subscribe to the query. That function accepts a resolve and reject callback, similar to a promise. The resolve function will receive an update, which will at first be an array of entities, then will be an update object with instructions that updateArray uses to update the original array.

let smiths: (User & UserData)[] = [];
pubsub.subscribeEntities(
  {
    class: User
  },
  {
    type: '&',
    like: ['name', '% Smith']
  }
)(
  (update) => {
    // This function will be called once initially with an array of
    // entities, then again every time there's a change with an
    // update object.
    // The updateArray function will add any newly matching entities,
    // update any existing entities that have changed, and remove any
    // entities that no longer match (including deleted entities).
    pubsub.updateArray(smiths, update);
  },
  (e) => {
    alert('Error: ' + e.textStatus);
  }
);

You can also receive a count of how many subscribers there are to that query. The count is given to a third callback.

let smiths: (User & UserData)[] = [];
pubsub.subscribeEntities(
  {
    class: User
  },
  {
    type: '&',
    like: ['name', '% Smith']
  }
)(
  (update) => {
    pubsub.updateArray(smiths, update);
  },
  (e) => {
    alert('Error: ' + e.textStatus);
  },
  (count) => {
    // This function will be called each time the count of
    // subscribers to this query changes.
    console.log(`There are now ${count} users watching the Smiths.`);
  }
);

To unsubscribe from the query, use the unsubscribe method on the PubSubSubscription object returned by the function.

let smiths: (User & UserData)[] = [];
let subscription = pubsub.subscribeEntities(
  {
    class: User
  },
  {
    type: '&',
    like: ['name', '% Smith']
  }
)((update) => {
  pubsub.updateArray(smiths, update);
});

onDestroy(() => {
  subscription.unsubscribe();
});

You can subscribe to changes to an entity with the subscribeWith method. This method accepts the callbacks directly and returns a PubSubSubscription object.

let subscription = pubsub.subscribeWith(
  smithEntity,
  () => {
    if (smithEntity.guid == null) {
      if (confirm('Someone deleted Mr. Smith! Do you want to restore him?')) {
        smithEntity.$save();
      }
    } else {
      alert("Mr. Smith's entity has changed!");
    }
  },
  (e) => {
    alert('Error: ' + e.textStatus);
  },
  (count) => {
    console.log(`There are now ${count} users watching Mr. Smith.`);
  }
);

onDestroy(() => {
  subscription.unsubscribe();
});

Warning: Subscriptions can lead to resource leaks if left open. Take care to unsubscribe to every query you are no longer watching.

Warning: The PubSub server is smart about removing entities that no longer match when a new entity matches, but there are some queries that can have changes in their matching entities without any change to the server (like relative time queries). These queries won't necessarily be updated correctly in due time by the PubSub server.

Previous: Entity Querying Next: Entity Class