Search code examples
angulartypescriptngxs

NGXS - How to package an action so that it can be dispatched remotely


I was recently looking into peer to peer messaging for a multi-user app. For this purpose i got the idea to send actions from one client to another.

Is it possible to serialize an action?

source.connection.send(action); // the type is not in the data?

destination.connection.on("data", data => this.store.dispatch(data)) 

Solution

  • There is official documentation and even a plugin that explains how to do this for websockets.


    The code required do this is however pretty simple, so here is my implementation for something besides web socket.

    export class SendAction {
        static readonly type = '[Connection] SendAction';
        public packedAction: any;
        constructor(action: any) {
            const type: string = action.__proto__.constructor.type;
            this.packedAction = { type: type, ...action };
        }
    }
    

    This will take an action as an argument, extract it's type string and data, and store this into the meta action under packedAction attribute.

    In the state you can add a handler that sends the packed action over some connection:

        @Action(SendAction)
        dispatch(context: StateContext<ConnectionModel>, action: SendAction) {
            this.connection.send(action.packedAction);
        }
    

    Finally on the receiver you can simply dispatch the transmitted action:

       connection.on('data', this.store.dispatch);
    

    To send an action to a client one can simply do:

    const action = new SomeAction("some payload");
    this.store.dispatch(new SendAction(action));
    

    Note that i would recommend filtering actions here, as the remote could dispatch any action defined.