Edit request body in Pre-request script

I’m trying to create a pre-request script for my collection as every request has some authentication data.

This is what I have:

let body = {
    mode: 'raw',
    raw: JSON.stringify({
        licenseUsername: 'username',
        licensePassword: 'password'
    }),
    options: {
        raw: {
            language: 'json'
        }
    }
}
pm.request.body.update(body);

Hey @seitzcasey,
You could also use variables to store the authentication data, so that in each request do you not have to repeat the username, password. You could read from the variable using
pm.variables.get("variable_key")

You can find more here - Variables in Postman

Let me know if that helps.

What I’ve found is the easiest is to just set it all to a variable. So take what you have and modify it slightly:

let body = {
    mode: 'raw',
    raw: JSON.stringify({
        licenseUsername: 'username',
        licensePassword: 'password'
    }),
    options: {
        raw: {
            language: 'json'
        }
    }
}
pm.variables.set('body', JSON.stringify(body));

Then in the body of your request, just use the variable
image

1 Like

I was hoping there was a way without having to do anything other that create the request inside my collection, set the endpoint and have it work. Is that possible?

Hi @seitzcasey,

So, just to be clear, you want to define a “Pre-Request” script within the collection, and not create actual Postman Request objects within the collection (as in a Request in the UI?)

If thats the case, then the way you’d like to achieve that wouldn’t be possible. You need at least one request in the collection to run an actual request.

If this is not what you are asking, please clarify a bit more, and I’ll be glad to provide more help :slight_smile:

No thats not what I meant. I want to avoid adding {{body}} each time I create a new request in postman. I want the collection level pre-request script to populate the request body without any extra action from the user.

So is the body identical for every request in your collection then?

Yes that is correct.

What was wrong with the approach you listed in your original post? What isn’t working with that?

The request doesn’t seem to be receiving the data. When I hit the postman echo endpoint, there are no args listed. But if I add them manually in the body tab, they do show.

Here is the manually entered body. As you can see, the “args” are correct.

Here is the pre-request script for the collection that this request is in.

Here is the response. As you can see, the “args” are not correct even though the console shows the correct output.

You cannot change the request body in that way using pm.request.body.update - Although it might log that to the console, it won’t change the main body of the request that’s sent.

2 Likes

Ah ok, thank you for the help.

I would like to add my support to this “feature request”. It would be great if we could change the request body before posting. For example :

pm.request.body.raw = JSON.stringify(pm.request.body.raw);

Is there any way to do this now?

1 Like

you can keep reqeust body as a vairable:

say

{{requestbody}}

now modify that variable instead and set the variable value as JSON.string using stringify:

pm.environment.set("requestbody", JSON.stringify({"somekey": "somevalue"}))

This works…

In Pre-request script, call a function defined in the Collection pre-request

//Formats the correct EHR_STATUS object template to adjust for differences between Better and ehrBase
pm.variables.set('ehrStatusTemplate',utils.formatEhrStatusTemplate(pm))

and the function in the Collection pre-request script is

utils = {
   formatEhrStatusTemplate: function(pm) {

        const useRandomSubjectId = false || pm.collectionVariables.get('UseRandomSubjectId') === 'true'

        const subbedSubjectId = pm.environment.replaceIn(useRandomSubjectId?'{{$guid}}':'{{subjectId}}')
       
        const ehrStatus = {
            _type: "EHR_STATUS",
            subject: {
                external_ref: {
                    id: {
                        _type: "HIER_OBJECT_ID",
                        value: subbedSubjectId,                 
                    },
                    namespace: '{{subjectNamespace}}',
                    type: "PERSON"
                }
            },
            is_modifiable: "true",
            is_queryable: "true"
        }                  
    
        console.log("esStatus",JSON.stringify(ehrStatus))

        let ehrStatusTemplate;
  
        if (!pm.environment.has('cdrProduct') || (pm.environment.get('cdrProduct') !== 'Better')) {
            const archetyped =  {  
                    archetype_node_id: "openEHR-EHR-EHR_STATUS.generic.v1",
                    name: "ehr status",

            }
            ehrStatusTemplate = { ...ehrStatus , ...archetyped}
        }
        else {
           ehrStatusTemplate = ehrStatus
        }
        return JSON.stringify(ehrStatusTemplate)
    },

}

Hah - doing this helped me fix an annoying issue that you although pm is in scope for a variable.get(), unless you explicitly pass pm into the function, you cannot do a .set(), or at least it is not persisted.

Just goes to show if you give … you get back!!

You have to set variable placeholders in the body itself, then set the variable values in the pre-request script. So you request body will be:

{
    mode: 'raw',
    raw: JSON.stringify({
        licenseUsername: '{{username}}',
        licensePassword: '{{password}}'
    }),
    options: {
        raw: {
            language: 'json'
        }
    }
}

…and in you pre-request script:

pm.variables.set("licenseUsername", "username-value");
pm.variables.set("licensePassword", "password-value");

This allows the flexibility of changing the body structure down the line without having to mess with the values themselves and/or the script.