> For the complete documentation index, see [llms.txt](https://docs.contextual.io/documentation-and-resources/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.contextual.io/documentation-and-resources/components-and-data/flows/node-reference/stream/map.md).

# Map

Applies an action to every item passing through a source stream.

A source node sends one carrier message containing a stream of message-shaped elements. Map adds an action that runs once for each element when the stream is consumed; nodes that are not source-aware receive the carrier once, not each element.

Use a **Map** node in your Flow to reshape items while they are still separate — stripping a property you do not want to return, renaming a field to match what a downstream system expects, or replacing an item with a single value from inside it. Doing this inside the stream is simpler than transforming a collected array afterwards and keeps the collected result small.

Map only works inside a stream. It must sit downstream of a node that opens one, such as *Source From* or a *Query Object* node with **Unfold all pages to source** enabled. *Map requires a source stream*.

To configure a **Map** node in the *Flow Editor*, drag it from the **Stream** group in the Palette to the Workspace canvas, then double-click the node to open and configure its behavior.

## Properties

* **Name** — optional display name for the node in the editor. By default, the node shows a label of "Map" followed by the selected action, for example Map (delete), so the configuration is visible on the canvas without opening the node. The value you provide here replaces that label.
* **Action** — what to do with each item. The fields shown below **Action** change with the action selected.

## Actions

### Set

Writes a value to a property on the item.

| **Field**        | **Purpose**              |
| ---------------- | ------------------------ |
| *target path*    | The property to write to |
| **to the value** | The value to write       |

**to the value** supports a msg property, number, string, boolean, JSON value, or JSONata expression. The editor does not offer flow, global, or environment context for this field.

If the selected msg property or JSONata expression resolves to `undefined`, Set deletes the target property.

### Delete

Removes a property from the item. Takes a single field, the path of the property to remove. No value is needed.

### Move

Relocates a value, writes it to the new path and removes the original property.

| **Field**   | **Purpose**          |
| ----------- | -------------------- |
| *from path* | The property to move |
| **to**      | Where to move it     |

**Move** takes two message-property paths. Its fields are typed inputs restricted to `msg` paths. The source path must exist: a missing final property can delete an existing destination, while a missing intermediate path causes stream consumption to fail.

For ordinary object properties, a new non-integer destination key is normally placed after the existing string keys. An existing destination retains its position, while integer-like keys follow JavaScript's numeric property-ordering rules.

### Concat

Flattens an item that holds an array, emitting each element as its own stream item.

| **Field**   | **Purpose**                                                     |
| ----------- | --------------------------------------------------------------- |
| *from path* | The property holding the array to flatten                       |
| **to**      | The literal top-level message key where each element is written |

Unlike the other three actions, Concat changes **how many items are in the stream**. Set, Delete and Move each turn one item into one item; Concat turns one item into as many items as the array holds.

With **from path** and **to** set to `payload`, a stream of three message-shaped elements whose payloads are `["NYC", "Boston"]`, `["Chicago"]`, and `["Seattle", "Austin"]` becomes five elements whose payloads are `NYC`, `Boston`, `Chicago`, `Seattle`, and `Austin`, in that order. Each output preserves the other top-level properties of the source element from which it was created. A downstream *Sink Collect* configured to collect `payload` returns those five values.

If the value at the source path does not provide an array `.map` operation, Concat fails when the stream is consumed. A downstream *Sink Collect* reports the error and emits no collected message; it does not emit an empty array.

A Concat applied to a stream of records whose source path holds a string produces no output at all, and a *Sink Collect* node downstream emits an empty array. Check that the path holds an array before using this action.

## Editing in place versus replacing the item

Set, Delete, and Move resolve the configured message path and leave unrelated properties untouched. Deleting `payload._metaData` removes that property while leaving the other payload and message properties unchanged.

Targeting `payload` replaces only the payload property of each stream element:

* **Set** target `payload.station` — the payload object keeps its existing properties and gains `station`
* **Set** target `payload` — the element's payload becomes the written value, while other top-level message properties remain

If *Sink Collect* is configured to collect `payload`, the collected entry contains only the resulting payload value.

## Map requires a source stream

A Map node must sit downstream of a node that opens a source stream. The editor marks a Map outside a source with a lint error:

```
Lint Errors:

- Does not have a source
```

Connecting Map within a source stream clears the lint error. If Map is nevertheless invoked without a source, it also reports the runtime error `source not initialized` and sends no output.

## Example

A weather application stores readings as records of the **weather app** Object Type. Every record carry a \_metaData property added by the platform, which is larger than the weather data itself. The /report2 endpoint strips it from each record before returning them.

```
[GET] /report2 → [Source] Query Objects → Map → Sink Collect → HTTP Response
```

### Open a stream

Configure the Query Objects node with **Type Id** weather app, **Query** {}, **Page Size** 10, and **Unfold all pages to source** enabled. The node opens a source whose message-shaped elements carry individual records at `payload`, and its editor label changes to \[Source] Query Objects.

### Configure the Map node

Set **Action** to Delete and the property path to payload.\_metaData. The node label on the canvas becomes Map (delete).

### Collect and respond

Add a *Sink Collect* node to close the stream, then an HTTP Response node.

### Confirm the result

Place a Log node between Map and Sink Collect and request /report2. Each record arrives with its weather data intact and no \_metaData:

```json
{
  "temperature": 12,
  "stationId": "Chennai",
  "id": "jbKBEsasrH3Tjqy6oXeWbA",
  "datetime": "2026-08-05T17:02:00.850Z"
}
```

Ten records produce ten entries. A Log node placed after Sink Collect shows a single entry containing all ten.

### Variations on the same flow

Changing only the Map node's configuration changes the shape of the response:

| **Configuration**                          | **Result per item**                      |
| ------------------------------------------ | ---------------------------------------- |
| **Delete** payload.\_metaData              | Record without its platform metadata     |
| **Move** payload.stationId to payload.city | Record with stationId renamed to city    |
| **Set** payload to msg.payload.stationId   | Record reduced to the station name alone |

The last of these turns the endpoint's response from an array of records into an array of strings.

**Concat** is not included above because it requires an array at the source path, which these weather records do not have. Applied to a stream whose items hold arrays, it flattens them and increases the number of items in the stream.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.contextual.io/documentation-and-resources/components-and-data/flows/node-reference/stream/map.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
