Skip to content

Query Bus

One of the buses used in storefront to handle queries within an application in a clean and robust way. Queries usually represent requests for information or data retrieval.

Queries can have only one listener at the time to ensure each one of them returns a single, definitive result, maintaining consistency and clarity in the system.

Query Bus Methods

The Query Bus utilizes methods that allow to handle commands depending on your needs.

  • on - allows to listen to the event similarly to how addEventListener works for DOM events.
  • once - allows to listen to an event only until it fires once. Then the listener is being removed.
  • off - allows to remove a listener from the event similarly to how removeEventListener works for DOM events.
  • execute - allows to execute a query asynchronously.
  • executeSync - allows to execute a query synchronously.
  • getListeners - allows to get all listeners of given message.
  • getListenersCount - allows to get the count of all listeners of given message.

Example

To listen to any query emitted by the Query Bus you can use the on method:

useStorefront(async (storefront) => {
    storefront.queryBus.on('example-query', () => {
        console.log('Listening to the query...')
    });
});

Example

Remember that the query bus does not allow two listeners:

useStorefront(async (storefront) => {
    storefront.query.on('example-query', () => {
        console.log('Listening to the query...')
    });

    storefront.queryBus.on('example-query', () => { // Error: Maximum number of listeners reached
        console.log('Listening to the query for the second time...')
    });
});

Listening with on and once at the same time is also not allowed:

useStorefront(async (storefront) => {
    storefront.query.once('example-query', () => {
        console.log('Listening to the query...')
    });

    storefront.query.on('example-query', () => { // Error: Maximum number of listeners reached
        console.log('Listening to the query with on...')
    });
});

Example

To remove a listener from any query of the Query Bus you can use the off method:

useStorefront(async (storefront) => {
    function myFunction(query) {
        console.log('Query:', query.name);
    }

    storefront.queryBus.on('query-name', myFunction);

    storefront.queryBus.off('query-name', myFunction);
});

Example

To execute a query of the Query Bus asynchronously you can use the execute method:

useStorefront(async (storefront) => {
    storefront.queryBus.execute({
        name: 'my-query',
        type: 'query',
        body: 'query body'
    });
});

Your body can contain any data type you need:

useStorefront(async (storefront) => {
    storefront.commandBus.execute({
        name: 'my-body',
        type: 'body',
        body: [
            {
                name: 'example1',
                values: [1, 2, 3]
            },
            {
                name: 'example2',
                values: [10, 20, 30]
            }
        ]
    });
});

Example

In this example we execute a query of the Query Bus synchronously and listen to it:

useStorefront(async (storefront) => {
    function getBodyLength(query) {
        // whenever this query executes return the length of a body
        return typeof query.body === 'string' ? query.body.length : 0;
    }

    storefront.queryBus.on('get-body-length', getBodyLength);

    const bodyLength = storefront.queryBus.executeSync({
        name: 'get-body-length',
        type: 'query',
        body: 'query body'
    });

    console.log('body length:', bodyLength);
});

Your body can contain any data type you need:

useStorefront(async (storefront) => {
    function getBodyLength(query) {
        // whenever this query executes return the length of a body
        return typeof query.body === 'string' ? query.body.length : 0;
    }

    storefront.queryBus.on('get-body-length', getBodyLength);

    storefront.queryBus.executeSync({
        name: 'my-body',
        type: 'body',
        body: [
            {
                name: 'example1',
                values: [1, 2, 3]
            },
            {
                name: 'example2',
                values: [10, 20, 30]
            }
        ]
    });

    console.log('body length:', bodyLength);
});

Example

To get the count of all listeners for a given message using the Query Bus you can use the getListenersCount method:

useStorefront(async (storefront) => {
    const listenersCount = storefront.queryBus.getListenersCount('my-query');

    console.log('listeners of my-query:', listenersCount);
});