Postman Pre-Request Script to Read Variables from CSV file and Append to JSON Body

I have a JSON body with template to pass to an API endpoint in Postman/Newman as follows:

{
  "total": [
    {
      "var1a": "ABCDE",
      "var1b": {
        "var2a": "http://url/site/{{yyyy}}/{{mmdd}}/{{yyyymmdd}}.zip",
        "var2b": {
           "var3a": "{{yyyymmdd}}",
           "var3b": "GKG"
        },
        "var2c": "ABCDE"
        "var2d": "{{p}}"
      }
    },
    {
      "var1a": "ABCDE",
      "var1b": {
        "var2a": "http://url/site/{{yyyy}}/{{mmdd}}/{{yyyymmdd}}.zip",
        "var2b": {
           "var3a": "{{yyyymmdd}}",
           "var3b": "GKG"
        },
        "var2c": "ABCDE"
        "var2d": "{{p}}"
      }
    }
}

Everything enclosed in double braces is a variable that needs to read from an external CSV file, which looks like:

p,yyyymmdd,yyyy,mmdd
1,19991231,1999,1231
2,20001230,2000,1230
  • Note that the CSV isn’t necessarily 2 entries long - I’d ideally like it to take in a dynamic number of entries that append after the last.
  • Ideally, I’d get rid of the last two columns in the CSV file (yyyy and mmdd) and have the code just do a slice as needed.

How do I even begin coding the pre-request script?

Even if reading from an external CSV is not possible, or even coding within the pre-request script to do this, what is a quick one-liner in Javascript or Python that can quickly give me the output I need so that I can just manually place it in the request body?

I even tried using the Postman runner to do a “fake” run so that I can quickly extract the different JSON bodies, but even with this, there is no clean way that it does the export…

Hi @evidence8321

I haven’t full digested your question yet but in terms of splitting the value you could do something like this;

let date = 20220627; // <-- Change to variable from CSV
let dateAsString = date.toString();

let year = dateAsString.substr(0, 4);
let monthDay = dateAsString.substr(4, 4);

console.log("year = ", year);
console.log("monthDay = ", monthDay);

Output;
image

Could you explain this in a little more detail, please?

Thanks! Yes - this explains perfectly how to split the value - I can hopefully get rid of those last two columns.

To clarify on the bigger problem…

What I meant was, the “input” CSV could look anything like:

p,yyyymmdd,yyyy,mmdd
1,19991231,1999,1231
2,20001230,2000,1230

OR

p,yyyymmdd,yyyy,mmdd
1,19991231,1999,1231
2,20001230,2000,1230
3,19991231,1999,1231
4,20001230,2000,1230
5,19991231,1999,1231
6,20001230,2000,1230

ie. I’d like the JSON body to read the variables from any number of rows from a given CSV using just the template JSON:
“var1a”: “ABCDE”,
“var1b”: {
“var2a”: “http://url/site/{{yyyy}}/{{mmdd}}/{{yyyymmdd}}.zip”,
“var2b”: {
“var3a”: “{{yyyymmdd}}”,
“var3b”: “GKG”
},
“var2c”: “ABCDE”
“var2d”: “{{p}}”
}
},

I think this is what you are looking for;
Being able to manipulate the iterations based on the total row count in your CSV.

If it’s not, let me know… I may have misunderstood your need.

I would like to run the request only once - so a runner is not useful here.
Before running the request, I’d like the JSON body to read by iterating over the input CSV (w/ reading from the pre-request script), and then run the request.

Hopefully, this makes sense… It’s 1:45 am and I’m very tired :rofl:

So if my understanding is correct, you are trying to loop through a CSV to build a payload, that can then be sent as a request body for a subsequent call.

If this is correct then the below code should give you what you need…

Note: Request 1 has to loop through all the rows so the iteration count has to be set to the number of rows. Otherwise, you will not see the total row count for the CSV.

But we will use postman.setNextRequest() to control when the second request gets triggered;
image


The code;

//Get 'p' and 'date' from CSV and set as collection level variables 
pm.collectionVariables.set("p", pm.iterationData.get('p'));
pm.collectionVariables.set("date", pm.iterationData.get('yyyymmdd'));
//Convert to strings
let pAsString = pm.collectionVariables.get("p").toString();
let dateAsString = pm.collectionVariables.get("date").toString();
//Use substr to get only part of the string
let year = dateAsString.substr(0, 4);
let monthDay = dateAsString.substr(4, 4);
//----------------------------------------------------------
if(pm.info.iteration === 0){
    //If it's the first iteration, declare a fresh array
    let myArray = [];
    //Push the new value to array 
    myArray.push('{"var1a":"ABCDE","var1b":{"var2a":"http://url/site/' + year + '/' + monthDay + '/' + dateAsString + '.zip","var2b":{"var3a":"' + dateAsString + '","var3b": "GKG"},"var2c":"ABCDE""var2d":"' + pm.iterationData.get('p') + '"}}');
    //Save array to collection variables
    pm.collectionVariables.set("myArray", myArray);
}
else if(pm.info.iteration > 0){
    //If it is not the first iteration then set myArray to the value of the current saved array
    let myArray = pm.collectionVariables.get("myArray");
    //Push the new value to array 
    myArray.push('{"var1a":"ABCDE","var1b":{"var2a":"http://url/site/' + year + '/' + monthDay + '/' + dateAsString + '.zip","var2b":{"var3a":"' + dateAsString + '","var3b": "GKG"},"var2c":"ABCDE""var2d":"' + pm.iterationData.get('p') + '"}}');
    //Save array to collection variables
    pm.collectionVariables.set("myArray", myArray);
}
//----------------------------------------------------------
if (pm.info.iteration === (pm.info.iterationCount-1)){
    //If the iteration is the same number of rows in the CSV then go to Request 2
    postman.setNextRequest("req2");
}
else{
    //If the iteration is NOT the same number of rows in the CSV (It hasn't reached the end of the file) then do nothing
    postman.setNextRequest(null);
}

Once this completes, request 2 outputs the full array that has been built using pm.collectionVariables.get("myArray");. This variable would be your payload.

Example of output;