Server Event

Overview

@serverEvent is a method decorator used in the implemenmtation of UI Components for WebMap to encapsulate the WebMap's events calls to the server.

UI Components emit events like click, textChanged, the @serverEvent decorator is used in the handlers of these events to trigger the corresponding event in the server, for example: the click DOM event might correspond to the Click (with uppercase) event in the server.

The events in the server can also receive arguments, the @serverEvent decorator provides a mechanism to obtain and send arguments as required.

!!! info Read more about Typescript's decorators at: https://www.typescriptlang.org/docs/handbook/decorators.html

To avoid sending unhandled events to the server, the implementation of @serverEvent checks that the called event is specified in the collection of handled events that each UI Component should have.

The main idea behind the @serverEvent decorator is to encapsulate this WebMap's exclusive code in the decorator's implementation and avoid code duplication in the implementation of the UI Components. There's no need to bind the events in the HTML of the Form that uses the component for the @serverEvent to be executed.

The typical server call is made using the Send command using code invocation like this:

public SomeFunction(event: EventData) {
    return this.webmapService.invoke(new Mobilize.Ui.v5.Command.Send(this.model, 'Button_Click', event.Id, "Click"));
}

Usage

The @serverEvent decorator should be used in every event of a UI Component that has a corresponding event in the server.

Basic Example

Let's suppose we have a TextComponent that sends every keyup event to the server, and in the server the corresponding event is named KeyUp. Below is a sample implementation of the HTML template and Typescript code of this component.

File: text.component.html

<input type="text" (keyup)="myKeyHandler($event)"/>

File: text.component.ts

@Component({
    selector: 'sample-text',
    styleUrls: ['./text.component.scss'],
    templateUrl: './text.component.html'
})
export class TextComponent extends ControlComponent {

    constructor(private changeDetector: ChangeDetectorRef) {
        super(changeDetector);
    }

    @Output()
    MyCustomKeyEvent: EventEmitter<EventData> = new EventEmitter<any>();

    @serverEvent('KeyUp')
    myKeyHandler(event: any): void {
        this.MyCustomKeyEvent.emit(event);
    }
}

Sending Arguments

The events in the server can receive arguments, for this purpose the @serverEvent decorator can receive a function that returns an object that will be sent to the server as the arguments.

This function is called Arguments Extractor and it receives as parameters the original event object emitted and the instance of the component that emitted the event.

Example

In the previous example of TextComponent we wanted to send every keyup event to the server so we added the @serverEvent('KeyUp') decoration, but we haven't specified how to send the actual key for each ocurrence of the event.

Now we will create an function named keyExtractor that will be used to provide the pressed key when sending the event to the server.

File: text.component.ts

@Component({
    selector: 'sample-text',
    styleUrls: ['./text.component.scss'],
    templateUrl: './text.component.html'
})
export class TextComponent extends ControlComponent {

    constructor(private changeDetector: ChangeDetectorRef) {
        super(changeDetector);
    }

    @Output()
    MyCustomKeyEvent: EventEmitter<EventData> = new EventEmitter<any>();

    // Now we add the 'keyExtractor' function to the decorator parameters
    @serverEvent('KeyUp', this.keyExtractor)
    myKeyHandler(event: any): void {
        this.MyCustomKeyEvent.emit(event);
    }

    keyExtractor(event: any, component: TextComponent): object {
        if (event.key) {
            // Object formatted to the arguments expected by the server event
            return { key: event.key }
        }
        return null;
    }
}

As you can see, it was very easy to add a function that allow us to specify which arguments we want to send to the server.