# Iterating

## Overview

Often, as part of some programming operation, it is necessary to iterate over a part or all of a foundset.

There are several approaches to iterating: using the foundset iterator, changing the selected index of the foundset, accessing a record object, accessing data provider values as an array.

While the last three iterating options are more intuitive, and also vary with regards to performance and usage, the foundset iterator is the most recommended to be used since it is the only option that ensures iterating over all the records of the foundset, without missing any of them due to the multiple clients performing changes on the same foundset at the same time.

It is also possible to use [JSFoundsetUpdater](/reference/servoycore/dev-api/database-manager/jsfoundsetupdater.md#jsfoundsetupdater) API to iterate over and update a foundset, though iterating is not its main goal.

## Using the Foundset Iterator

Sometimes there is more than one user working on the same foundset, possibly inserting or deleting records. Thus, in such cases, a secure iterator is needed to perform the iteration on the foundset.

**Use Case**: Best for ensuring complete iteration over all records, especially in multi-user environments where records might be added or removed concurrently. This method ensures no records are skipped or processed multiple times due to concurrent modifications.

The `forEach` method of the foundset iterator is designed to iterate over **all** records in a foundset, ensuring that each record is processed once even if other users are modifying the foundset simultaneously. This method provides a callback function that is called for each record in the foundset.

**Example**: This is an example of how to use the `forEach` method for iterating over a foundset.

```javascript
foundset.loadAllRecords();
foundset.forEach(
    /**
     * @param {JSRecord} record
     * @param recordIndex
     * @param {JSFoundset} fs 
     */
    function(record, recordIndex, fs) {
        application.output("record processed: " + record + ", record index: " + recordIndex);
    }
);
```

See also: [JSFoundset's forEach](/reference/servoycore/dev-api/database-manager/jsfoundset.md#foreach-callback) method.

## Changing the Selected Index

Changing the selected index of a foundset involves programmatically setting the foundset's selected index property. This approach iterates over the foundset by moving the selected index from one record to the next. While this method is simple and intuitive, it may have performance drawbacks due to the repeated UI updates.

**Use Case**: Intuitive for operations where interacting with the UI's currently selected record is necessary. This method is straightforward for developers to understand and implement.

**Example**: The example below iterates over the **entire** foundset using a for loop.

```javascript
for (var i = 1; i <= foundset.getSize(); i++) {
    foundset.setSelectedIndex(i);
    // operate on the selected record
}
```

See also: [JSFoundset's setSelectedIndex](/reference/servoycore/dev-api/database-manager/jsfoundset.md#setselectedindex-index) method.

## Accessing a Record Object

While setting the selected index of the foundset is sometimes necessary, it also contains some overhead and therefore is not always the most efficient way to iterate over a foundset. However, one can iterate in a similar manner, access a record object without changing the selected index of a foundset by using the getRecord method of the foundset.

**Use Case**: Useful when you need to iterate without affecting the selected index, avoiding side effects on the UI. This method is more efficient than changing the selected index and prevents unnecessary UI updates.

**Example**: This example iterates over the foundset, but does not affect the selected index. The performance will be better than the previous example, and will not have any side effects in the UI if the foundset is bound to a form.

```javascript
for (var i = 1; i <= foundset.getSize(); i++) {
    var rec = foundset.getRecord(i);  // does not affect the selected index
}
```

See also: [JSFoundset's getRecord](/reference/servoycore/dev-api/database-manager/jsfoundset.md#getrecord-index) method.

## Accessing Data Provider Values As an Array

When the goal is to access all values for a particular data provider, obtaining an array of values using `getFoundSetDataProviderAsArray` is the most efficient approach. This method retrieves the values of a specific data provider for all records in the foundset as an array, allowing for fast iteration and processing.

**Use Case**: Ideal for bulk operations on a specific data provider, such as gathering or processing values. This method provides the best performance when only specific data provider values are needed.

**Example**: This example shows how to access all the values in a foundset for a single data provider. Iterating over a simple array offers better performance over normal foundset iteration.

```javascript
var ids = databaseManager.getFoundSetDataProviderAsArray(foundset, 'order_id');
for (var i in ids) {
    var id = ids[i];
}
```


---

# 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.servoy.com/guides/develop/programming-guide/working-with-data/iterating.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.
