---
id: scripting-javascript
title: "JavaScript script"
summary: "Write a step in JavaScript on V8. The async execute function, flow classes, services, fetch, timers and console, values, batches and debugging."
audience: user
keywords: "javascript, js, script, execute, v8, fetch, async, await, console, services, debugging"
---
# JavaScript script

The **JavaScript script** component runs your JavaScript for every record that reaches it, on Google's V8 engine.
`async`/`await`, `fetch`, timers and `console` work as you expect.

## What you write

Connect the input and output first, then open the editor. The template is generated from the connections:

```javascript
async function execute(metaData, inputData) {
	const outputData = new CustomerDto();
	services.Next(metaData, outputData);
}
```

Every type of the flow is a JavaScript class with the same property names (`inputData.Email`).

## How it runs

- The script loads once when the flow starts. Top-level code runs then, and global variables keep their values between
  records.
- For every record the component calls `execute(metaData, inputData)` and waits until it finishes.
- Each component handles one record at a time.

## Sending records on

`services.Next(metaData, obj)` sends a record to the components connected to `Output`; call it once, several times or
not at all. `obj` is an instance of a flow class (`new CustomerDto()`), not a plain object.
`await services.NextAsync(metaData, obj)` waits until the record is delivered.

## Values

| Flow type | In JavaScript |
|---|---|
| List | An array: `length`, `for...of`, `map`, `filter`, `push`, `splice`; assign a whole array to replace it |
| Date | `Date` |
| Decimal | `number`; assign a string (`"12345678901234.123"`) for an exact decimal |

## What's available

- **`services`**: the [flow services](./services), with the C# member names. Methods that return a .NET `Task` return
  a promise.
- **`fetch(url, { method, headers, body })`**: works like in a browser. An object body is sent as JSON. HTTP error
  statuses come back as a response with `ok` false.
- **`console`**: `log`, `info`, `warn`, `error` and `trace` write to the designer's trace console.
- **Timers**: `setTimeout`, `setInterval`, and `sleep(ms)`.
- **`crypto`**.

There are no modules: `require`, `import` and npm packages are not available.

## Debugger

Start the flow with **Debug** (Ctrl+F5) and set breakpoints in the editor margin. The debugger stops on them and shows
the local variables. Step with F10, F11 and Shift+F11; continue with F5.

## Errors

An error that leaves `execute` goes to the flow's error handling, with your script's stack and the error line marked
in the editor. To report an error and carry on, catch it and call
`await services.HandleExceptionAsync(metaData, inputData, error)`.

## Example

```javascript
let counter = 0;

async function execute(metaData, inputData) {
	if (!inputData.Email) return;          // filtered out
	const outputData = new CustomerDto();
	outputData.Name = inputData.Name.toUpperCase();
	outputData.Email = inputData.Email.toLowerCase();
	counter++;
	services.Messaging.UpdateStatusMessage(`Mapped ${counter}: ${outputData.Email}`);
	services.Next(metaData, outputData);
}
```
