---
id: awe-106
title: awe-106 Actions and dependencies
sidebar_label: awe-106 Actions and dependencies
---

In this tutorial we will see how to give some *dynamism* to the screen that we have developed. Thanks to **[actions](#actions)** and **[dependencies](#dependencies)** it is possible to make requests to the server, to modify the content of a component given the values of other components or to change the attributes of a criteria.

## Actions

Actions are executions that can be done on client (browser) or server. This executions may be launched in an ordered way (synchronous executions) or in parallel (asynchronous executions).

Right now, actions may be launched from buttons (`button-action`) and dependencies (`dependency-action`). Both kinds of actions work in the same way and have the same attributes, the only difference between them is the time they are launched. The former ones are launched when you *click* the button and the latter ones are when the conditions of the [launchers](#launchers) of the [dependency](#dependencies) are met.

### Client related

There are several kinds of actions that may be executed on the client. The attribute `type` indicates the action we want to execute. The list of available actions can be found [here](/api/actions.md#client-actions).

```xml
<button-action type="reset"/>
```

This action will delete the content of all criteria and grids on the screen.

<img alt="Reset criteria" src={require('@docusaurus/useBaseUrl').default('img/training/reset.gif')} />

When we want the action to be executed on a specific component, we can use its `name` in the `target` attribute of the action:

```xml
<button-action type="filter" target="[grid ID]"/>
```

This action will tell a grid to *reload* with the attributes it has defined.

<img alt="Grid filter" src={require('@docusaurus/useBaseUrl').default('img/training/filter.gif')} />

Actions also allow us to navigate between application screens, in this case the `target` attribute says what option we want to access:

```xml
<button-action type="screen" target="name of screen we want to navigate to"/>
```

This action will indicate the system to change the screen for a new one.

<img alt="Navigation action" src={require('@docusaurus/useBaseUrl').default('img/training/navegacion.gif')} />

Sometimes we want to show a dialog asking for confirmation with a message that we may define like [this](/api/messages.md):

```xml
<message id="message identifier" title="message title" message="message description"/>
```

To open a dialog that uses this message, we will define an action of type `confirm`:

```xml
<button-action type="confirm"  target="message identifier"/>
```

This action will open a dialog with a confirmation message like the following:

<img alt="Confirmation action" src={require('@docusaurus/useBaseUrl').default('img/training/confirmacion.gif')} />

If the user clicks **Accept**, already defined actions will be launched. If clicks **Cancel** then the action stack to be launched will be emptied.

> There are other actions like `validate` that also act on the action stack depending on the result. In case that validation is not successful, this action **cancels** the rest.

### Server related

There are some actions that are [launched against the server](/api/actions.md#server-call). These actions start with the word `server` and they require a series of extra attributes: the type of action that we want to execute in the server (`server-action`) and the identifier of that action (`target-action`):

```xml
<button-action type="server"  server-action="action in the server" target-action="action identifier"/>
```

If the action returns data (is of type `data` or `value`), we can say the action to what component we want to give the received data:

```xml
<button-action type="server"  server-action="action that returns data" target-action="action identifier" target="component that receives the data"/>
```

<img alt="Server action => actions returned by the server" src={require('@docusaurus/useBaseUrl').default('img/training/accion-servidor.gif')} />

Most of times, actions send to the server return more actions, that are stored in the stack before the pending actions (unless they are asynchronous). These actions returned by the server will be executed before the rest and one of them may even cancel the rest (type `cancel`).

### Synchronous launching

Inside of a button or a dependency of type *action* you can define as many actions as you need:

```xml
<button label="BUTTON_CONFIRM" icon="save" id="ButCnf" help="HELP_CONFIRM_BUTTON">
    <button-action type="validate" />
    <button-action type="confirm" target="id mensaje" />
    <button-action type="server" server-action="maintain" target-action="id maintain server" />
    <button-action type="server" server-action="maintain-silent" target-action="id maintain server" />
    <button-action type="filter" target="id componente" />
</button>
```

By default, all action defined are synchronous (they are executed sequentially  given the order of execution), and no action is executed until the previous one ends. There are some actions, like `cancel`, that remove the rest of actions from the **current** action stack.

<img alt="Action stack" src={require('@docusaurus/useBaseUrl').default('img/training/pila.gif')} />

While the **current** action stack contains actions in execution, all buttons in the application are **disabled** (to avoid the overload of actions).

<img alt="Disabled buttons" src={require('@docusaurus/useBaseUrl').default('img/training/botones-deshabilitados.gif')} />

If we open a modal dialog with `dialog` action, the **current** stack will freeze and a new one will be created that will manage dialog's actions and will become the **current** stack:

```xml
<button-action type="dialog"  target="dialog identifier"/>
```

When opening a new stack, the enabled/disabled state of buttons will depend on the new stack.

<img alt="Modal dialog and new stack" src={require('@docusaurus/useBaseUrl').default('img/training/acciones-dialogo.png')} />

### Asynchronous launching

There is an attribute that modifies the way an action works: `async="true"`

```xml
<button-action type="server"  server-action="action that returns data" target-action="action identifier" target="component that receives data" async="true"/>
```

This action is stored in the stack of *synchronous* actions, as with the rest, but when it time to be executed arrives, it is removed from the *synchronous* stack (and the next one is executed), added to the *asynchronous* one and executed inmediatly.

<img alt="Asynchronous actions" src={require('@docusaurus/useBaseUrl').default('img/training/acciones-asincronas.png')} />

This allows **several requests to the server** or **concurrent updates** of several componentes to be launched. The fact that they are initially stored in the stack of synchronous actions is because this way we can cancel them if, for instance a validation fails or a confirmation is cancelled by the user.

### Accesing actions workflow

AWE offers a tool for developer that allows to visualize the execution of the defined actions. For this, it is necessary to open browser's console and write:

```javascript
angular.element(document.body).injector().get("AweSettings").get().actionsStack = 500;
```

This adds a *delay* in the execution of 500 milliseconds (you may change the amount) and also shows the execution of actions in each of the stacks. To the left you can find the asynchronous stack and to the right the synchronous. The **current** stack is the one found to the left of the synchronous stack.

## Dependencies

Dependencies, along with actions, offer dynanism to the generated screen almost effortlessly. They can [act on the component where they are defined](#on-the-component) or [launch one or several actions on any screen component](#launching-actions).

Dependencies are defined inside of the interactable components of the application: 

**On a button:**
```xml
<button ...>
	...
	<dependency ...>
	</dependency>
</button>

```

**On a criteria:**
```xml
<criteria ...>
	<dependency ...>
	</dependency>
</criteria>
```

**On a grid:**
```xml
<grid ...>
	...
	<dependency ...>
	</dependency>
</grid>
```

For a dependency to be launched, all the conditions defined in **[launchers](#launchers)** must be met. In the dependency a series of **[modifiers](#modifiers)** can be defined to treat the conditions of the launchers.

By default, the launching of the dependency is done when **all** conditions are met (`and`).

### Launchers

Launchers are the **conditions to be met** for a dependency to be launched. The syntax goes as follows:

```xml
<dependency ...>
	<dependency-element id="component identifier" condition="launching condition"/>
</dependency>
```

By default, launching condition is `is not empty`, that say, that the component has a value. Everytime the value of the component changes, **all launchers** will be checked and if all of them are valid, dependency will be launched.

#### Value

Value launchers are those that check the **value of a component**. If the value meets the defined condition, launcher is valid. For instance:

```xml
<dependency ...>
	<dependency-element id="criterioA"/>
</dependency>
```

> This dependency will be launched when *criterioA* has any value or when it changes.

```xml
<dependency ...>
	<dependency-element id="criterioA" condition="eq" value="value1"/>
</dependency>
```

> This dependency will be launched when *criterioA* has value `value1`

```xml
<dependency ...>
	<dependency-element id="criterioA" condition="gt" value="3"/>
	<dependency-element id="criterioA" condition="ne" id2="criterioB"/>
</dependency>
```

> This dependency will be launched when the value of *criterioA* is greater than `3` and the value of *criterioA* is different from *criterioB*'s.

#### Attribute

In some components we need the **value of an attribute** to launch the dependencies. **[Each type of component has a series of attributes](/api/dependencies.md#attributes)** that can be checked:

```xml
<dependency ...>
	<dependency-element id="criterioA" attribute="unit" condition="eq" value="EUR"/>
</dependency>
```
> This dependency will be launched when the unit of *criterioA* is `EUR`.

When working with `grid`s and `treegrid`s is necessary to define the column we want to access to to recover the value:

```xml
<dependency ...>
	<dependency-element id="gridA" column="columnaA" attribute="selectedRowValue" condition="eq" value="R"/>
</dependency>
```
> This dependency will be launched when the cell on column *columnaA* and **selected row** from *gridA* has the value `R`. In editable grids, the selected row is the one being edited in that moment.

<img alt="selectedRowValue" src={require('@docusaurus/useBaseUrl').default('img/training/selectedRowValue.gif')} />

Attributes are also useful to retrieve values from cells in a row and perform calculations with them. With `currentRowValue` the value of the current row is retrieved (these dependencies will be over columns, because otherwise is imposible to know the value of the *current row*).

```xml
<column name="columnaC" component="text">
    <dependency ...>
        <dependency-element id="gridA" column="columnaA" attribute="currentRowValue" alias="valorColumnaA"/>
        <dependency-element id="gridA" column="columnaB" attribute="currentRowValue" alias="valorColumnaB"/>
    </dependency>
</column>
```
> This dependency retrieves the values of cells *columnaA* and *columnaB* from the **same row** where *columnaC* can be found. On their own, these launchers would not execute the dependency, simply it would be taken into account that those cells had any value. It would be necessary to include a **[event launcher](#event)** that would cause a recalculation of the whole grid.

#### Event

Along with attributes, **[some components launch events](/api/dependencies.md#events)** at a given time. These events can be used to launch dependencies.

For instance, if we use the previous example and add anevent launcher, the dependency will be launched and the values of those columns will be retrieved every time that event is fired:

```xml
<column name="columnaC" component="text">
    <dependency ...>
        <dependency-element id="gridA" column="columnaA" attribute="currentRowValue" alias="valorColumnaA"/>
        <dependency-element id="gridA" column="columnaB" attribute="currentRowValue" alias="valorColumnaB"/>
        <dependency-element id="botonA" event="click"/>
    </dependency>
</column>
```
> Every time a user clicks on button *botonA*, whole column *columnaC* from grid *gridA* will be recalculated.

<img alt="Recalculation with button" src={require('@docusaurus/useBaseUrl').default('img/training/recalculo-boton.gif')} />

We can do it even more dynamic and, every time someone edits and saves a row, we will launch the recalculation:

```xml
<column name="columnaC" component="text">
    <dependency ...>
        <dependency-element id="gridA" column="columnaA" attribute="currentRowValue" alias="valorColumnaA"/>
        <dependency-element id="gridA" column="columnaB" attribute="currentRowValue" alias="valorColumnaB"/>
        <dependency-element id="gridA" event="save-row"/>
    </dependency>
</column>
```
> Every time someone saves a modification on a row, column *columnaC* from grid *gridA* will be recalculated.

<img alt="Recalculation of a column" src={require('@docusaurus/useBaseUrl').default('img/training/recalculo-save-row.gif')} />

#### Modifiers

There are a series of modifiers that change the way the expressions of launchers are evaluated by default: the **[initial evaluation](#initial-evaluation)**, the **[kind of evaluation](#kind-of-evaluation)** to be done and the **[reverse evaluation](#reverse-evaluation)**.

##### Initial evaluation

Sometimes is necessary to perform an initial launch of the dependency to **check if it has to be launched** (by default, this is not done because it would make the application to perform quite badly). To indicate to a dependency that it should make an initial check of values when loading the screen, it is necessary to set the `initial` attribute to "true":

```xml
<dependency initial="true" ...>
	<dependency-element id="criterioA" condition="gt" value="3"/>
	<dependency-element id="criterioA" condition="ne" id2="criterioB"/>
</dependency>
```
> This dependency will check when the screen is loaded the values from criterias *criterioA* and *criterioB* and will launch the dependency if conditions are met.

##### Kind of evaluation

By default, a dependency is launched when **all launchers** meet the conditions defined. This can be changed when the attribute `type="or"` (by default its value is `"and"`), that will launch the dependency when **any of the launchers** meet the condition defined.

```xml
<dependency type="or" ...>
	<dependency-element id="criterioA" condition="gt" value="3"/>
	<dependency-element id="criterioA" condition="ne" id2="criterioB"/>
</dependency>
```
> This dependency will be launched when the condition of the first launcher is met (`criterioA > 3`) **or** when the conditions of the second is met (`criterioA != criterioB`).

##### Reverse evaluation

Some dependencies (not all of them, only the ones having **[reversible actions](#acting-on-the-component)**) require another dependency to be included to restore the modified value in case that the conditions are not met. To facilitate this kind of dependencies, there is an attribute (`invert="true"`) that evaluates in the oposite way the conditions defined in the launchers, so if we define the following dependencies:

```xml
<dependency ...>
	<dependency-element id="criterioA" condition="gt" value="3"/>
	<dependency-element id="criterioA" condition="ne" id2="criterioB"/>
</dependency>
<dependency invert="true" ...>
	<dependency-element id="criterioA" condition="gt" value="3"/>
	<dependency-element id="criterioA" condition="ne" id2="criterioB"/>
</dependency>
```

**if first dependency is not launched, second will be**, and viceversa.

#### Saving data from launcher

Launchers may be used also to recover data from other components that are needed for the execution of the dependency (for instance, to calculate a formula). To do this, we need to give an `alias` in the launcher where we will indicate the identifier that will be used to obtain the value retrieved:

```xml
<criteria type="numeric" id="suma">
    <dependency initial="true" source-type="formule" target-type="input" formule="[a] + [b]">
        <dependency-element id="numeroA" alias="a"/>
        <dependency-element id="numeroB" alias="b"/>
    </dependency>
</criteria>
```

This dependency will be launched when components `numeroA` and `numeroB` **have value** (and also everytime those values change), and also everytime it does it it will update the value of the criteria `suma` with the sum of the values of the components. Also, it will check the value of components `numeroA` and `numeroB` when loading the screen and **will launch the dependency if both have values defined initially** (because `initial` attribute is set to `true`). 

### On the component

Once all conditions of components are met, the dependency is executed. Usually a dependency retrieves one or several data and with that it updates the component where is defined.

#### Origin of data

The `source-type` attribute defines the **[origin of data](/api/dependencies.md#source-type)** that will be used to **modify the component where the dependency is defined**.

By default, the `source-type` is `none`, meaning that if **left undefined, it does not try to recover any data**.

**The origin of data** may be **one of the launchers** (`source-type="launcher"` would retrieve the value of the alias defined in the `target-action` attribute)

```xml
<criteria type="numeric" id="copia">
    <dependency source-type="launcher" target-type="input" target-action="a">
        <dependency-element id="criterioA" alias="a"/>
    </dependency>
</criteria>
```

a **static value** (`source-type="value"`, that would retrieve the value from `value` attribute in the dependency)

```xml
<criteria type="text" id="estatico">
    <dependency source-type="value" target-type="input" value="estatico">
        <dependency-element id="criterioA" alias="a"/>
    </dependency>
</criteria>
```

the **execution of a formula** (`source-type="formule"` defined in `formule` attribute)

```xml
<criteria label="a" id="a" component="numeric" style="col-xs-6 col-sm-3 col-lg-2" value="3"/>
<criteria label="b" id="b" component="numeric" style="col-xs-6 col-sm-3 col-lg-2" value="6"/>
<criteria label="a + b" id="aplusb" component="numeric" style="col-xs-6 col-sm-3 col-lg-2">
<dependency source-type="formule" target-type="input" formule="[a] + [b]">
  <dependency-element id="a"/>
  <dependency-element id="b"/>
</dependency>
</criteria>
<criteria label="a * b" id="amultipliedbyb" component="numeric" style="col-xs-6 col-sm-3 col-lg-2">
<dependency initial="true" source-type="formule" target-type="input" formule="[a] * [b]">
  <dependency-element id="a"/>
  <dependency-element id="b"/>
</dependency>
</criteria>
```

<img alt="Formula dependency" src={require('@docusaurus/useBaseUrl').default('img/training/dependencia-formule.gif')} />

> As can be seen, when loading the page the first calculation **is not done**, because it is not defined as `initial="true"`

or by the **data recovered by a query** done on the server (`source-type="query"` that requires also the attributes `server-action` and `target-action`).

```xml
<grid id="grid">
	<column name="columna1"/>
    <column name="columna2"/>
    <dependency source-type="query" target-type="input" server-action="data" target-action="consulta">
        <dependency-element id="criterioA" alias="a"/>
        <dependency-element id="criterioB" condition="ne" value="raro"/>
    </dependency>
</grid>
```

<img alt="Query dependency" src={require('@docusaurus/useBaseUrl').default('img/training/dependencia-query.gif')} />

#### Acting on the component

The attribute `target-type` indicates the **[part of the component to be updated](/api/dependencies.md#target-type)** with the data calculated or recovered from `source-type`. Those parts may be the actual value of the component (`input`), the `label` of a criteria, the `unit`, etc.

In some cases, **[is not necessary to recover a data to act on a component](/api/dependencies.md#target-type)**, but 
knowing if the conditions of the dependency have been met or not. This happens with actions like `show`, `set-required`, etc.

```xml
<button id="boton">
    <dependency target-type="enable">
        <dependency-element id="criterioA" condition="eq" value="lala"/>
    </dependency>
</button>
```
> This dependency would activate the button only when the *criterioA* has the value 'lala'

**[Some actuations are reversible](/api/dependencies.md#target-type)**, meaning that, if dependency's conditions are not met, the oposite action is executed, so **it is not necessary to include two dependencies** (one that acts as we want and another to do the opposite when the inverse conditons are met). This happens with actions like `show`, that will launch a `hide` action in case conditions are not met, an `enable` would launch a `diable`, etc.

```xml
<criteria id="criterioB" type="text">
    <dependency target-type="show">
        <dependency-element id="criterioA" condition="eq" value="mostrar"/>
    </dependency>
</criteria>
```
> This dependency would show the *criterioB* only when *criterioA* has the value 'mostrar'. Otherwise, the criteria is kept hidden.

<img alt="Reversible actuation" src={require('@docusaurus/useBaseUrl').default('img/training/actuacion-reversible.gif')} />

### Launching actions

Until now, all dependencies that we have seen act solely **on the component** (criteria, grid, column, chart) where it was defined. There are other kind of dependencies, action dependencies, that can be defined in any component but they only **launch the actions** (`dependency-action`) that they have defined inside, they do not act with the component.

These dependencies are defined setting to `action` the attribute `source-type`, one or more launchers are defined and afterwars actions are added (as `dependency-action`):

```xml
<dependency source-type="action">
  <dependency-element id="gridA" attribute="selectedRows" condition="eq" value="1" />
  <dependency-element id="gridA" event="select-row" />
  <dependency-action type="server" server-action="data" target-action="accion de servidor" target="gridB"/>
</dependency>
```
> This dependency will launch a data load on *gridB* when we select one and only one row of *gridA*.

<img alt="Selection of a row reloads another grid" src={require('@docusaurus/useBaseUrl').default('img/training/seleccionar-fila-recarga-grid.gif')} />

### Launching order

Dependencies are evaluated in **the order they are defined**. If there is more than one dependency defined on the same component that **matches the conditions to be executed in that moment**, they will **be executed in a synchronous way** (in the order they are defined).

```xml
<criteria id="criterioA" component="hidden">
  <dependency source-type="launcher" target-type="input" target-action="valor">
    <dependency-element id="criterioB" alias="valor"/>
    <dependency-element id="botonA" event="click"/>
  </dependency>
  <dependency source-type="launcher" target-type="input" target-action="valor">
    <dependency-element id="criterioC" alias="valor"/>
    <dependency-element id="botonA" event="click"/>
  </dependency>
</criteria>
```
> In the previous dependency, the criteria *criterioA* will take the value from *criterioC* because **they are executed in order**, the value from the first dependency **will be overwritten** (value from *criterioB*) given that criteria *criterioC* has any value.

### Performance

Dependencies affect to the performance of a screen (a lot of calculation is done on the browser). Adding **too many dependencies** to a window may cause a **bad user experience**, so it is necessary to design ccorrectly the funcionality we want to offer and look for possible alternatives (like updating criteria and grids massively, or initializing the data when the screen loads).