# 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:

```typescript
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`

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

File: `text.component.ts`

```typescript
@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`

```typescript
@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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.gapvelocity.ai/webmap/general/frontend/documentation/winforms-angular-components/decorators/server-event.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
