# The stateManager.on() method
This documents the `stateManager.on()` method.

There are multiple parameters for this method, and a deeper dive into each of them can be found in the [Events -> Introduction page](/documentation#Events/6-events-intro) and all of the pages within the Events category.


## How to listen, what is the general schema?
Generally, the format is just:
```ts
taClient.stateManager.on('eventType', () => {
    // callback function
})
```
or
```ts
async function handleEvent(params) {
    // code here
}

taClient.stateManager.on('eventType', handleEvent);
```

Essentiallly both are the same thing. The point is that when an event happens, depending on your subscription type, different types of data will be passed through to a method(callback). Once you start to listen to events, you will listen until you *remove* the listener or *disconnect* the client.

Find documentation on how to remove a listener at the [State Manager -> RemoveListener page](/documentation#State%20Manager/2-stateManager-removeListener)

I will provide an example from ShyyTAUI which listens to the `matchDeleted` and `matchUpdated` events.
```ts
// Handle match events
// Handle when a match is updated. This happens when a new map is set, or something about the match chages like authorised users
async function handleMatchUpdated(params: [Match, Tournament]) {
    // Log the request for debugging and clarity
    console.log("Match updated:", params);
    // Check if the updated match guid is the same as the match we are in-s guid
    if (params[0].guid === matchGuid) {
        // If it is, update the match variable to ensure that we see the latest data
        match = params[0];
        // Since the song might have changed, let's refresh the song data(from BeatSaver)
        await refreshMatchDetails(params[0]);
    }
}

// Handle when a match is deleted
function handleMatchDeleted(params: [Match, Tournament]) {
    // Just log the packet in console to ensure that I know what is happening
    console.log("Match deleted:", params);
    // Check if the match that got deleted was the one the user was just in
    if (params[0].guid === matchGuid) {
        // If yes then navigate back to the create or join match screen without resetting the state
        goto(`/tournaments/${tournamentGuid}`);
    }
}

// This is triggered when the component is loaded
onMount(async() => {
    if ($authTokenStore) {
        // Using stateManger listen to global changes to our match
        client.stateManager.on('matchDeleted', handleMatchDeleted);
        client.stateManager.on('matchUpdated', handleMatchUpdated);
    } else {
        window.location.href = "/discordAuth"
    }
});

// This is triggered when the component is destroyed
onDestroy(() => {
    // Remove the listeners that were added on mount
    client.stateManager.removeListener('matchUpdated', handleMatchUpdated);
    client.stateManager.removeListener('matchDeleted', handleMatchDeleted);
});
```
<div class="info-box">
    <span class="material-icons">info</span>
    <div>
        <strong>Example:</strong> This is an example from the page of ShyyTAUI within the match cordination page. 
    </div>
</div>

As you may see, the `params` variable in the method / callback had the same type in the `matchUpdated` and `matchDeleted` case. Generally it is very easy to even guess what the packet should include, as it of course includes the details of whta its name entails. In this case it was a simple array with a `Match` and `Tournament` object inside it. 

<div class="warning-box">
    <span class="material-icons">warning</span>
    <div>
        <strong>IMPORTANT:</strong> When you listen to events, rather than only listening in the current tournament, it listens globally!
    </div>
</div>

The above warning is important to consider. Since this is the `stateManager`, it will receive updates for the global state. That includes any tournament-s details that you are authorised to view. So say you are in *Tournament 1*, and then get a `matchUpdated` packet. This DOES NOT mean that the match you are currently in for updated. It means that a match (the object of which is passed on in `params[0]`) has been updated in the tournament(the object of which is passed on in `params[1]`). This tournament can however be *Tournament 57* as far as we are concerned. You must have authorisation for the tournament in order to actually receive these events. Although even in my implementation I discard this `Tournament` object, it can prove useful a lot of times. An example of this is when a user disconnects. You want to know if that user was in your tournament or not.