Access data from CSV or JSON files during collection runs in Requestly API client scripts.
The rq.iterationData object reads the current row of a data file when you run a collection with the Collection Runner. Each iteration of the run gets the next row (CSV) or object (JSON) from the file, so the same requests run with different inputs.
rq.iterationData holds values only when you run a collection with a data file attached. When you send a single request, or run a collection without a data file, it is empty: get returns undefined and toObject() returns {}.
key (string): The column (CSV) or property (JSON) name
Returns: The value, or undefined if the row has no such name. The value keeps the type the data file gave it: see Value types. A value you set earlier in the same script comes back as set stored it.Example:
// For a CSV with columns: city, temperatureconst city = rq.iterationData.get("city");const temp = rq.iterationData.get("temperature");console.log(`Weather in ${city}: ${temp}°C`);// Output: Weather in Vancouver: 10°C
Adds or changes a value in the current row, for the rest of this script only. See How values are saved.Parameters:
key (string): The name. It must not be empty.
value (any): The value. It is kept exactly as you pass it. null or undefined removes the value, the same as unset(key).
type (string, optional): The type to give the value before it is stored: "string", "number", "boolean", "array", "object" or "any". You can also pass { type }.
Checks whether the current row has a value with this name.Parameters:
key (string): The column (CSV) or property (JSON) name
Returns:true if the row has the name, otherwise false.Example:
if (rq.iterationData.has("userId")) { const userId = rq.iterationData.get("userId"); console.log("User ID:", userId);} else { console.log("No user ID in this iteration");}
Returns the current row as one object of names and values.Returns: An object such as { city: "Vancouver", temperature: 10 }. Each value has the type get returns for it.Example:
Replaces each {{name}} in a template with the value of that name in the current row.Parameters:
template (string, object or array): Text containing {{name}} references. In an object or an array, every string inside is replaced.
Returns: The template with the references replaced. A value that is not text is written the way JavaScript’s String() writes it, so an array becomes a,b. A name the row does not have, and a dynamic variable such as {{$guid}}, stays as written. Each reference is replaced once, so a {{name}} inside a value stays as written. To replace names from every scope, use rq.variables.replaceIn.Example:
Returns a plain copy of rq.iterationData, the same as toJSON(), with every {{name}} inside it replaced. For a plain object of names and values, use toObject().Parameters:
scope (object, optional): The object whose replaceIn replaces the references. Pass rq.variables to replace names from every scope. Defaults to rq.iterationData.
overrides (array of objects, optional): Objects whose properties are copied onto the result, in order.
Returns: An object with id and values, plus mutations once you have called enableTracking().Example:
Copies the names and values of a plain object into the current row, for the rest of this script only. An existing name gets the new value, and a new name is added. Names the object does not have are kept. The changes are not recorded in mutations.Parameters:
object (object): The names and values to copy in
track (boolean, optional): Set to true to get back what changed
Returns: With track set to true, an object that maps each new name to "created" and each name whose value changed to "updated". A name whose value did not change is not listed. Without track, undefined.Example:
// "retries" is in the row and "region" is notconst changes = rq.iterationData.syncVariablesFrom({ region: "eu", retries: 5 }, true);console.log(changes); // { region: "created", retries: "updated" }
The current row, as a list.Each item is one value with key, value, type and disabled. Call the item’s get() to read its value, and its set(value) to change it.The list has these methods:
Read:one(key) returns the item with that name, and get(key) its value. has(key) checks whether the list holds that name. count() returns the number of items, all() an array of them, idx(index) the one at a position, and indexOf(key) its position, or -1. toObject() returns an object of names and values, and toJSON() an array of plain { key, value, type } items.
Loop:each(fn), map(fn), filter(fn), find(fn) and reduce(fn, initial) work like the array methods of the same name. fn receives each item and its position.
Change:add({ key, value, type, disabled }) adds an item. upsert({ key, value, type, disabled }) updates the item with that name, or adds it when there is none. remove(key) removes the item with that name, and remove(fn) removes every item fn returns true for. clear() removes every item.
Text:replace(text) replaces each {{name}} in text with the list’s value for that name.
Copy:syncFromObject(object, track?, prune?) works like syncVariablesFrom, and with prune set to true it also removes the names the object does not have. syncToObject(object?) works like syncVariablesTo.
Changes made through values last for the rest of this script only, like set, and are not recorded in mutations.Example:
A record of the set and unset calls this script made on rq.iterationData, in order. It exists only after you call enableTracking(); until then, mutations is undefined. clear() records an unset for each value it removes, and applyMutation records the call it makes. Changes made through values or syncVariablesFrom are not recorded.
stream (array): One entry per call: [key, value] for set and [key] for unset
compacted (object): The last change to each name, filled by compact() or by autoCompact
count(): Returns the number of recorded changes
compact(): Keeps only the last change to each name, moving the entries from stream into compacted
applyOn(target): Makes the recorded changes again on another object, such as rq.variables
Starts recording set and unset calls in a new mutations record. rq.iterationData does not record changes until you call this. Calling it again while recording does nothing. After disableTracking(), it starts a new, empty record.Parameters:
options (object, optional): { autoCompact: true } keeps only the last change to each name, in mutations.compacted
Adds a list of variables to read when the current row has no value with that name. get, has, toObject and replaceIn read the lists in the order you add them. Writes still go to the current row only.Parameters:
list: Another object’s values, such as rq.environment.values
Example:
rq.iterationData.addLayer(rq.environment.values);const region = rq.iterationData.get("region"); // the environment's value when the row has none
Values in rq.iterationData are never saved. set, unset, clear and the other methods that change the row affect the rest of the current script only. The data file does not change, and every later script, even the post-response script of the same request, reads the row as the data file holds it.To pass a value to the scripts that run after this one, write it to another scope, such as rq.variables:
JSON file: Numbers, booleans, null, objects and arrays come back as they are written.
CSV file: A cell that holds a number, or true or false, comes back as a number or a boolean. Every other cell comes back as text, and an empty cell as "".
// Post-response scriptconst expectedStatus = rq.iterationData.get("expectedStatus");const actualStatus = rq.response.code;rq.test(`Status code matches expected (${expectedStatus})`, function() { // A number in the data file is already a number rq.expect(actualStatus).to.equal(expectedStatus);});