My question:
There are two parts to this question setting environment vars based on the size of some array but then using those environment vars in a post request
Details (like screenshots):
//Get the size of the Zone array, how many zones
const requestBody = JSON.parse(pm.request.body.raw)
const numOfZones = requestBody.zones.length;
const zoneConfigIDs =
//Generate UUIDs for the id key for each zone for as many zones as there are
for (let i = 0; i<numOfZones; i++)
{
// pm.environment.set(“zoneConfigID”,uuid.v4().toUpperCase())
// zones[i].id = uuid.v4().toUpperCase()
const zoneConfigID = uuid.v4().toUpperCase()
zoneConfigIDs.push(zoneConfigID)
pm.environment.set(“zoneConfigID”,JSON.stringify(zoneConfigIDs[i]))
console.log(zoneConfigIDs[i])
}
Now using the env. var(s) created from pre-request in the actual post call body:
“zones”: [
{
“id”: “{{zoneConfigID}}”
},
{
“id”: “{{zoneConfigID}}”,
}
]
How I found the problem:
with the few things i tried I either get the last UUID generated for all id fields (when they need to be unique per zone) or I get the array of UUIDs as string [“uuid1”,“uuid2”] or i get the literal string {{zoneConfigID_{$i}}}
I’ve already tried:
I have tried to use “id”: “{{zoneConfigID_${i}}}”
and also in the pre-script while setting the env. var
I wouldn’t set the values as environment variables (as there could be a lot based on the size of the array).
But you can update the values within the body with something similar to the following in a pre-request script.
No need to mess around with array indexes.
const body = JSON.parse(pm.request.body.raw);
// console.log(body);
body.zones.forEach(zone => {
zone.id = pm.variables.replaceIn("{{$guid}}");
// console.log(zone.id)
});
pm.request.body.raw = body;
// console.log(pm.request.body.raw)
1 Like
First thanks for the reply,
I agree that the size of the array could mean a lot of env. vars, I actually have a number of working solutions similar to what you suggested but I wanted to learn if there is a way I could simply set a single env. var with a rotating index
something like:
pm.environment.set(zoneConfigID_${i}
, zoneConfigID);
without having to manipulate the raw payload body, the following works but I am making changes to the raw payload body:
// // Generate UUIDs for the id key for each zone for as many zones as there are
// for (let i = 0; i < zonesArraySize; i++) {
// zonesArray[i].id = pm.variables.replaceIn(uuid.v4().toUpperCase());
// }
// // Update the request body with the modified zones array
// pm.request.body.raw = JSON.stringify(requestBody, null, 2);
I am approaching this the same way we can do something like this:
var zoneName = “Zone 1”
pm.environment.set(“zoneName”, zoneName)
and then reference that directly in the json payload body
{
“name”: “{{zoneName}}”,
…
}
Your original post had an example body that included multiple objects, each with their own “id”.
I assumed that you needed to ensure each id was unique and its a single POST request sending all of those id’s at the same time.
Therefore, the following won’t work as the variable name is not unique and will get get overwritten each time with the latest value.
pm.environment.set(“zoneConfigID”,JSON.stringify(zoneConfigIDs[i]))
You would have to turn it on its head, and make the variable name dynamic as well as the value, and then reference it by the correct variable name in the body.
I can’t see how you would have a single environment variable that could be used.
You might need to explain the rotating index concept, as I’m not sure what you mean by that. Not in a single POST request. It could be done if it was multiple POST requests, each with a single zone\ID each time using the JavaScript array.shift() method and setNextRequest (to keep looping through the same request).
Do you know how many zones\id’s will be sent each time?
First sorry for not getting back sooner, and I appreciate your help
Yes that’s correct multiple IDs and each one needs to be unique. The single variable was getting overwritten you’re right in that aspect.
This is a configuration end-point, so it has to be done in a single POST otherwise I need to check if there is support for PUT or UPDATE in order to make multiple calls and in each call have a single zone ID
I think for now I have a working solution, which requires the use of
pm.request.body.raw = JSON.stringify(requestBody, null, 2);
which is altering or updating the request body directly
and 2 options
either using the
pm.environment.set(zoneConfigID_${i}
, zoneConfigID);
and with that reference the actual index in the request body so something like
“Id”:{{zoneConfigID_0}}, and _1 and so on
or
use the replaceIn function() and directly access the json keys for example body.zoneConfig.Id but of course make an array of the zone IDs size and iterate over them
Like I said I have a working solution I just wanted something simpler like a typical pm.environment.set() but I guess because we have the same key multiple times that won’t be as simple as we normally set environment variables
This has been informational and helped me understand how to work with dynamic environment variables and more so when there are arrays involved
actually @michaelderekjones I am in this situation because I wasn’t able to use {{$guid}} postman built in function directly (although very handy) because the end-point expects uppercase
I tried to use {{$guid.toUpperCase())}} but doesn’t seem to work so that’s why I had to write a pre-request script otherwise i could have used the {{$guid}} directly in the json payload body without the need for any scripting
unless you know of a way
You can’t use the toUpperCase() JavaScript function in the body (as you can’t have code in the body).
You can amend the pre-request script I provided to change it to uppercase.
const body = JSON.parse(pm.request.body.raw);
console.log(body);
body.zones.forEach(zone => {
zone.id = (pm.variables.replaceIn("{{$guid}}")).toUpperCase();
console.log(zone.id)
});
pm.request.body.raw = body;
console.log(pm.request.body.raw)
right makes sense
Cool thanks for the help
here is my final working solution for other’s benefits:
// Get the size of the zones array in the request body, how many zones
const requestBody = JSON.parse(pm.request.body.raw);
const zonesArray = requestBody.zones;
const zonesArraySize = zonesArray.length;
console.log(zonesArray);
// Generate UUIDs for the id key for each zone for as many zones as there are
for (let i = 0; i < zonesArraySize; i++) {
zonesArray[i].id = pm.variables.replaceIn(uuid.v4().toUpperCase());
//Now do the Modules inside each zone
const modulesArray = zonesArray[i].modules
const modulesArraySize = modulesArray.length
for (let j = 0; j < modulesArraySize; j++)
{
modulesArray[j].id = pm.variables.replaceIn(uuid.v4().toUpperCase())
}
}
// Update the request body with the modified zones array
pm.request.body.raw = JSON.stringify(requestBody, null, 2);
Here is an alternative method:
/*
This method uses an env var as an indexed array
but would need to hardcode the index in the payload zoneConfigID_0, zoneConfigID_1…etc.
*/
// Get the request body as a string
// const requestBody = pm.request.body.raw;
// // Parse the request body as JSON
// const requestBodyJson = JSON.parse(requestBody);
// // Determine the size of the zones array
// const zonesCount = requestBodyJson.zones.length;
// // Generate UUIDs for each zoneConfigID and set environment variables
// for (let i = 0; i < zonesCount; i++) {
// const zoneConfigID = uuid.v4().toUpperCase();
// pm.environment.set(zoneConfigID_${i}
, zoneConfigID);
// }
// // Log the generated UUIDs
// console.log(pm.environment.toObject());