Can I use pm.sendRequest() to send requests synchronously within a pre-request script?

I have a little test setup that I need to do in my pre-request scripts and what I really need is that the scripts run in sequence and wait for the sendRequest before to complete before moving on.

I am find lots of conflicting information on the web, some saying that preRequest scripts are async, some claiming this is not longer an issue in the latest version of postman.

Can anyone clear this up? If it’s supported, can someone point me in the right direction (an example would be nice?)

Hey @josephadams,

Welcome to the community! :trophy:

Are you are to give an example of what you’re trying to do and what you have in the app right now. Just trying to visualize what’s going on. :grin:

Which we’re the articles that had the conflicting information?

Issue I need to test a delete endpoint. In order to test this, I want to do a few support tasks in the pre-request scripts. First one is to find out how many items I have in my results, second is create a new item (which I will use to delete) and third is to get the new largest Id (and pass this to the end point.)

Code

// first we need to establish how many categories we have
pm.sendRequest({
    url: 'http://localhost:8888/api/blog/categories/',
    method: 'GET',
}, function (err, res) {
    varResponseData = res.json();
    console.log('b4 ' + res.json().length);
    pm.variables.set('beforeDeleteTesting', res.json().length);
});

// now we need to create a new category which we will delete 
pm.sendRequest({
    url: 'http://localhost:8888/api/blog/categories/',
    method: 'POST',
    header: 'content-type: application/json', 
    body: {
        mode: 'raw',
        raw: JSON.stringify({ name: "Super Dooper" })
    }
}, function (err, res) {
    // console.log(res);
    setTimeout(function(){}, 2000)
});

// finally we will get the biggest id (which will be the one we have created) and use this as part of our delete call
pm.sendRequest({
    url: 'http://localhost:8888/api/blog/categories/',
    method: 'GET',
}, function (err, res) {
    varResponseData = res.json();
    // console.log(res.json());

    max = Math.max(...varResponseData.map(user => user.id));
    console.log('max val ' + max);
    pm.variables.set('idToDelete', max);
    setTimeout(function(){}, 2000)
});

Result The requests all fire off at the same time and the wrong result is deleted.

I have seen some places saying that I should use callbacks (but haven’t seen any examples) while the same thread suggested that an improvement was coming in Postman (again, I couldn’t confirm this via any searching) - someone else suggested using a done() keyword as in some other frameworks, but then this was contradicted by another user.

I had seen some article (which I can’t find now) which seemed to suggest normal requests (those in the body) would behave properly, but I’ve never written anything like the above in a body.

1 Like

Flow

So at this point, I have 3 entries returned by the API:
[
    {
        "id": 1,
        "name": "Cat 1"
    },
    {
        "id": 2,
        "name": "Cat 2"
    },
    {
        "id": 3,
        "name": "Cat 3"
    }
]

Based on this, I’d expect the following console output:
“b4: 3” (the first pm.sendRequest should see we have 3 categories present
the second pm.sendRequest will return a null when a new category is created.
the third pm.sendRequest should return 4 (as this will be the id of the newly created category.
so,
b4: 3
null
4
(And then 4 is deleted and we move to tests.)

Actual output
b4 3
max val 3

And when I check the entries, the wrong id number has been deleted.

1 Like
[
    {
        "id": 1,
        "name": "Cat 1"
    },
    {
        "id": 2,
        "name": "Cat 2"
    },
    {
        "id": 4,
        "name": "Super Dooper"
    }
]

the entry with id of 4 should not be present, but due to the timing, 3 was deleted instead of 4.

1 Like

Were you ever able to figure this out? I am also looking for how to send a synchronous request and update variables before executing additional requests.

Why don’t you just add a request in your collection to do the prep work?

You’re hitting APIs to setup this test data, I can’t see a reason why it would need to be all done in a pre-request script.

My use case is I’m executing the pre-request script to get the access token, setting that to a Collection variable, and then using that as the Bearer token for API requests. Currently, I have to manually execute the request to get the access token then copy/paste it into the Authorization tab for each API request I run.

So my goal with this is to eliminate this step of manually running the script to get the access token and copy/pasting it. If there’s some way to do this other than in the pre-request that I might be missing I’d be happy to try it out!

You could try the method I describe in this blog post:

https://www.readysetcloud.io/blog/allen.helton/how-to-automate-oauth2-token-renewal-in-postman-864420d381a0/

It has worked for my team and I, we use it every day.

1 Like

That did work! I was using different syntax for a callback, including it as the second arg of pm.sendRequest seems to have done the trick. Thanks!

:boom: Awesome! I’m super happy to hear it!