# event

Agents, Widgets and Applications are loosely coupled in a Dashboard plugin, but it is still very easy to communicate between your them, as well as with the Dashboard and even with other plugins.

## How to use

```javascript
import { Plugin } from'@root'

const events = Plugin.event('my-custom-event-uuid')
```

## Event instance

event instance has custom methods to be called to communicate:

| property | type     |
| -------- | -------- |
| send     | function |
| on       | function |
| ready    | function |
| off      | function |

## send

We will start in your agent class. Let's say that you want to send an event to your application based on if your api is up and running.

We would then write the following code:

```javascript
import { Plugin } from'@root'

class Agent extends Plugin.Agent {
    ...
    const eventPayload = {
        status: true
    }
    
    // you can access events methods from any Base-Components when you extend yours with
    this.send({
        name: 'pluginName:apiStatus',
        userData: eventPayload
    })
      
    //  Or create your own events instance
    this.events = Plugin.event('my-events-instance-uuid')
    this.events.send({
        name: 'pluginName:apiStatus',
        userData: eventPayload
    })
    ...
}
```

As default all events are broadcasted, to everyone listening to the event name. If you want to target a specific type of plugin or even an instance of an app, widget or agent you can send an extended event. For example when you want to respond to a previous event.

### Target a plugin

```javascript
events.send({
	name: 'pluginName:apiStatus', // Name of the event
	target: 'com.naviga.dashboard-plugin-bundle', // The bundle id of the target type
	userData: {
		status: true
	}
})
```

### Target an event instance

```javascript
events.send({
	name: 'pluginName:apiStatus', // Name of the event
	targetUUID: EVENT_INSTANCE_UUID, // The UUID of the target type (more info in **on**)
	userData: {
		status: true
	}
})
```

We call the dispatch send function with the event payload and the event name.

{% hint style="info" %}
Best practice here for event names is to use your plugin name, followed by : and then what type of event\
name: 'pluginName:apiStatus'
{% endhint %}

## on

To listen to this event inside your application class simply write

```javascript
events.on('pluginName:apiStatus', userData => {
    console.log("Api is up and running: ", userData.status)
})
```

What is happening here is that we subscribe to the "pluginName:apiStatus" event.

And we then asynchronously receive the data in the userData object.

Dashboard will set reserved properties in userData object that you can't override with your own values which they are:

| property | value                                                              |
| -------- | ------------------------------------------------------------------ |
| \_sender | a custom object for events instance details                        |
| UUID     | the events instance uuid that the send methods has been fired from |

the UUID can be used to answer back to the current events instance who just end the message

```javascript
events.on('pluginName:apiStatus', userData => {
    console.log("Api is up and running: ", userData.status)
    
    events.send({
        name: 'pluginName:apiStatusResponse',
        targetUUID: userData.UUID,
        userData: {
            // custom data or empty object
        }
    })
})
```

## ready

Plugins can be loaded, installed and activated in different order so if a plugin have dependency to another plugin we can use `events.ready()` to know when it's ready to communicate with.

For example if one plugin talks to an API and another plugin wants to use that data. We do this by listening to the bundle id of the target plugin.

If the target plugin is already loaded the callback will fire instantly.

```javascript
events.ready('com.naviga.dashboard-APIPlugin', () => {
    events.send({
        name: 'apiPlugin:search',
        userDate: {
            query: 'dashboard'
        }
    })
})
```

## off

When a component is unmounted from the DOM it is necessary to unregister the events dispatcher, otherwise callbacks can be called when your component is not mounted and this can cause your plugin to try to modify unmounted node elements.

In other words, hell breaks loose.

```javascript
import { Plugin } from '@root'

import {
    useRef,
    useEffect,
    Component
} from 'react'

const Application = prop() => {
    const events = (Plugin.event('event-uniq-id'))
    
    useEffect(() => {
        return () => {
            events.off()
        }
    }, [events])
}

class Application extends Component {
    constructor(props) {
        super(props)
        
        this.events = Plugin.event('event-uniq-id')
    }
    
    componentWillunmout() {
        this.events.off()
    }
}
```


---

# 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.navigaglobal.com/dashboard-plugin/api-and-gui/api/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.
