How to send two pm.sendRequests sequentially?

I have 2 requests that needs to be done to set the authentication token , this token is passed to the REST call .
Here is the code that is there in the pre-tests

const siaPostRequest = {
url: ‘https://iam.stage1.bluemix.net/identity/token’,
method: ‘POST’,
header: {
‘Accept’: ‘application/json’,
‘Content-Type’: ‘application/x-www-form-urlencoded’

  },
  body: {
      mode: 'urlencoded',
      urlencoded: [
        {key: "grant_type", value: "urn:ibm:params:oauth:grant-type:apikey"},
        {key: "apikey", value: "xxx"},
        {key: "Accept", value: "application/json"},
        {key: "Content-Type", value: "application/x-www-form-urlencoded"}
    ]
  }

};

var getToken = true;

if (!pm.environment.get(‘accessTokenExpiry’) ||
!pm.environment.get(‘currentAccessToken’)) {
console.log(‘Token or expiry date are missing’)
} else if (pm.environment.get(‘accessTokenExpiry’) <= (new Date()).getTime()) {
console.log(‘Token is expired’)
} else {
getToken = false;
console.log(‘Token and expiry date are all good’);
}

if (getToken === true) {
pm.sendRequest(siaPostRequest, function (err, res) {
console.log(err ? err : res.json());
if (err === null) {
console.log(’***Abt to set the sia access token *******’);
var responseJson = res.json();
pm.environment.set(“sia_access_token”,responseJson.access_token);
console.log('token from env auth1 ’ + pm.environment.get(“sia_access_token”));

        var expiryDate = new Date();
        expiryDate.setSeconds(expiryDate.getSeconds() + 55);
        pm.environment.set('accessTokenExpiry', expiryDate.getTime());
    }
});

const siaDesiredPostRequest = {

url: ‘https://iam.stage1.bluemix.net/identity/token’,
method: ‘POST’,
header: {
‘Accept’: ‘application/json’,
‘Content-Type’: ‘application/x-www-form-urlencoded’

  },
  body: {
      mode: 'urlencoded',
      urlencoded: [
        {key: "grant_type", value: "urn:ibm:params:oauth:grant-type:iam-authz"},
        {key: "desired_iam_id", value: "crn-crn:v1:bluemix:public:siapoc::a/xxx:instance12345::"},
        {key: "Accept", value: "application/json"},
        {key: "Content-Type", value: "application/x-www-form-urlencoded"},
        {key: "access_token", value: pm.environment.get("sia_access_token")},
    ]
  }

};

pm.sendRequest(siaDesiredPostRequest, function (err, res) {
console.log(err ? err : res.json());
if (err === null) {
console.log(’******ABt to set the SIA desired token *************************’);
var responseJson1 = res.json();
pm.environment.set(“sia_desired_token”,responseJson1.access_token);
console.log(‘sia_desired_token’ + pm.environment.get(“sia_desired_token”));

    }
});

}

Here is the response from the log
******ABt to set the SIA desired token *************************

then

***Abt to set the sia access token *******

So it looks like the order of calling the requests are changed , it need to first then second as the first call output is fed to the second one .So the tests are failing.

pm.sendRequest is an asynchronous operation and you need to make the second request in the callback of the first one. This is the standard way to serially call two callback-based async operations in JavaScript.

pm.sendRequest(firstRequest, function (err, firstResponse)  {
  // add your extra logic here
  pm.sendRequest(secondRequest, function (err, secondResponse)  {
    // add your extra logic here
  });
});
1 Like

Hello @numaanashraf thanks for the tip. Now i see that environment variables are not getting set.

@krishnandoss08 Could you console.log the value you are trying to set in the script before setting it? It’ll help us rule out any cases where the value itself is not available in the script.

console.log('going to set env var ' + valueToSet);
pm.environment.set('envVar', valueToSet);

Also let us know whether the setting ‘Automatically persist variable value’ is on or off in Settings > General

hi @numaanashraf as you can see from the log many things are not being set
for e.g
going to set accessTokenExpiry **** 1538586098423
after setting accessTokenExpiry

there is no logging of this statement going to set sia_desired_token *****

This is a bug !

@krishnandoss08
Please provide the full pre-request script you ran along with the console logs. With just the logs, there is insufficient information for us to understand or replicate this issue.

@numaanashraf here is the full script

const siaPostRequest = {
  url: 'https: //iam.stage1.bluemix.net/identity/token',
    method: 'POST',
  header: {
    'Accept': 'application / json',
    'Content - Type': 'application / x - www - form - urlencoded'

  },
  body: {
    mode: 'urlencoded',
    urlencoded: [{
        key: "grant_type",
        value: "urn:ibm:params:oauth:grant-type:apikey"
      },
      {
        key: "apikey",
        value: "4YXfPuSZIDhGahHmClJZGFzaGai8xH9ViW4p0XLWvjVr"
      },
      {
        key: "Accept",
        value: "application/json"
      },
      {
        key: "Content-Type",
        value: "application/x-www-form-urlencoded"
      }
    ]
  }
};

var getToken = true;

if (!pm.environment.get('accessTokenExpiry') ||
  !pm.environment.get('currentAccessToken')) {
  console.log('Token or expiry date are missing')
} else if (pm.environment.get('accessTokenExpiry') >= (new Date()).getTime()) {
  console.log('Token is expired')
} else {
  getToken = false;
  console.log('Token and expiry date are all good');
}

if (getToken === true) {

  pm.sendRequest(siaPostRequest, function (err, siaPostres) {
    console.log(err ? err : siaPostres.json());
    if (err === null) {

      var responseJson = siaPostres.json();
      console.log('*** going to set sia_access_token \n ***   ' + responseJson.access_token);
      pm.environment.set("sia_access_token", responseJson.access_token);
      console.log('token from env auth1   ' + pm.environment.get("sia_access_token"));

      var expiryDate = new Date();
      expiryDate.setSeconds(expiryDate.getSeconds() + 55);
      console.log('going to set accessTokenExpiry ****   ' + expiryDate.getTime());
      pm.environment.set('going to set accessTokenExpiry ***', expiryDate.getTime());
      pm.environment.set('going to set currentAccessToken ****', 1);
      pm.environment.set('currentAccessToken', 1);
      console.log('after setting accessTokenExpiry   ' + pm.environment.get("accessTokenExpiry"));
    }

    const siaDesiredPostRequest = {
      url: 'https: //iam.stage1.bluemix.net/identity/token',
        method: 'POST',
      header: {
        'Accept': 'application / json',
        'Content - Type': 'application / x - www - form - urlencoded'

      },
      body: {
        mode: 'urlencoded',
        urlencoded: [{
            key: "grant_type",
            value: "urn:ibm:params:oauth:grant-type:iam-authz"
          },
          {
            key: "desired_iam_id",
            value: "crn-crn:v1:bluemix:public:siapoc::a/73be9f58fe97adebbf9fe13eeea2ebe4:instance12345::"
          },
          {
            key: "Accept",
            value: "application/json"
          },
          {
            key: "Content-Type",
            value: "application/x-www-form-urlencoded"
          },
          {
            key: "access_token",
            value: pm.environment.get("sia_access_token")
          },
        ]
      }
    };

    pm.sendRequest(siaDesiredPostRequest, function (err, siaDesiredPostres) {
      console.log(err ? err : siaDesiredPostres.json());
      if (err === null) {

        var responseJson1 = siaDesiredPostres.json();
        pm.environment.set('going to set sia_desired_token *****\n', responseJson1.access_token);
        pm.environment.set("sia_desired_token", responseJson1.access_token);
        console.log('sia_desired_token' + pm.environment.get("sia_desired_token"));


      }
    });

  });
}

@krishnandoss08 it is unclear what is the issue you are facing. From the script and logs, I see that the following environments are getting set properly ‘sia_access_token’ & ‘sia_desired_token’.

@numaanashraf

Dear @numaanashraf gretings. I hope to make it clear this time . Please read the message kindly again in a fresh pair of eyes.

firstly from the logs you would find that after setting the token , the next line getting the token is returning a empty.

another proof is the first image that i have uploaded , as you can see this is the screen from the environment editor screen where you see that even after the test run’s the variable data is not persisted.

If still these does not help you to discover the bug , can we have a short go to web meeting ? appreciate your help
Tx
k.thulsi doss

@krishnandoss08 Regarding the highlighted section in the logs, the environment variable you are logging out in the line ‘after setting accessTokenExpiry’ is not set anywhere. You are setting ‘going to set accessTokenExpiry ***’ in line 2 below and expecting it to be present in ‘accessTokenExpiry’ in line 5.

console.log('going to set accessTokenExpiry ****   ' + expiryDate.getTime()); 
pm.environment.set('going to set accessTokenExpiry ***', expiryDate.getTime());
pm.environment.set('going to set currentAccessToken ****', 1);
pm.environment.set('currentAccessToken', 1);
console.log('after setting accessTokenExpiry   ' + pm.environment.get("accessTokenExpiry"));

Regarding the environment not present in the UI, it is possible to export the collection and send it to us? We tried your use case with a simple collection and it works as expected.

The collection we tried is given below (you can import this into your app via Import > Paste Raw Text)

{
	"info": {
		"_postman_id": "37e91a2f-1d34-49e2-bcce-123e66931b27",
		"name": "Script Testing",
		"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
	},
	"item": [
		{
			"name": "pm.sendRequest with environment setting",
			"event": [
				{
					"listen": "prerequest",
					"script": {
						"id": "cd7e5b41-29a8-4000-8469-cf65a8d73232",
						"exec": [
							"pm.sendRequest('https://postman-echo.com/get?q=1', function (err, res1) {",
							"    let res1Data = res1.json();",
							"    pm.environment.set('env1', res1Data.args.q);",
							"    ",
							"    pm.sendRequest('https://postman-echo.com/get?q=2', function (err, res2) {",
							"        let res2Data = res2.json();",
							"        pm.environment.set('env2', res2Data.args.q);",
							"    });",
							"})",
							""
						],
						"type": "text/javascript"
					}
				}
			],
			"request": {
				"method": "POST",
				"header": [],
				"body": {
					"mode": "raw",
					"raw": ""
				},
				"url": {
					"raw": "https://postman-echo.com/post",
					"protocol": "https",
					"host": [
						"postman-echo",
						"com"
					],
					"path": [
						"post"
					]
				}
			},
			"response": []
		}
	]
}

If you could provide a collection like this, it’ll help a lot with triaging the issue at our end and advice why your use case is not working.

Dear @numaanashraf many thanks for the user error in script ,my bad (sorry). Yes i’m able to see the data after setting properly however i dont see those environement variables .

Thanks a Lot
k.thulsi doss

@krishnandoss08 Thanks for the collection/env. We’ll check and get back.

@numaanashraf could you please update your findings ? thanks a lot

@numaanashraf could you please help with a solution here. @kaustavdm ,please your attention here. We are needing a solution to this issue.
Tx
K.thulsi doss

@krishnandoss08 We were able to replicate the issue. We are investigating further.

We cleared the environment you had provided and it works as expected. Refer below:

Please bear in mind that environment values are “strings” if you set them via the UI. This can have an impact on the JavaScript logic you write in the pre-request script.

@numaanashraf , i modified the pre-tests as follows
const siaPostRequest = {
url: ‘https://iam.stage1.bluemix.net/identity/token’,
method: ‘POST’,
header: {
‘Accept’: ‘application/json’,
‘Content-Type’: ‘application/x-www-form-urlencoded’

  },
  body: {
      mode: 'urlencoded',
      urlencoded: [
        {key: "grant_type", value: "urn:ibm:params:oauth:grant-type:apikey"},
        {key: "apikey", value: "4YXfPuSZIDhGahHmClJZGFzaGai8xH9ViW4p0XLWvjVr"},
        {key: "Accept", value: "application/json"},
        {key: "Content-Type", value: "application/x-www-form-urlencoded"}
    ]
  }

};

let getToken = “true”;
let accessTokenExpiryLong=Date.parse(pm.environment.get(“accessTokenExpiry”));
let currentAccessToken=pm.environment.get(“currentAccessToken”);
console.log(“currentAccessToken”,currentAccessToken);

if (currentAccessToken ==“true” || accessTokenExpiryLong >=0)
{
console.log(‘Token or expiry date are missing’);
getToken = “true”;

} else if (accessTokenExpiryLong <= (new Date()).getTime()) {
console.log(‘Token is expired’);
getToken=“true”;
} else {
getToken = “false”;
console.log(‘Token and expiry date are all good’);
}

if (getToken === “true”) {

pm.sendRequest(siaPostRequest, function (err, siaPostres) {
console.log(err ? err : siaPostres.json());
if (err === null) {

        var responseJson = siaPostres.json();
         console.log('*** going to set sia_access_token \n ***   ' + responseJson.access_token);
        pm.environment.set("sia_access_token",responseJson.access_token);
        console.log('token from env auth1   ' + pm.environment.get("sia_access_token"));

        var expiryDate = new Date();
        expiryDate.setSeconds(expiryDate.getSeconds() + 55);
        console.log('going to set accessTokenExpiry ****   ' + expiryDate.getTime());
        pm.environment.set("accessTokenExpiry", expiryDate.getTime());
        console.log('going to set currentAccessToken  ');
        pm.environment.set("currentAccessToken", "false");
        
         console.log('after setting accessTokenExpiry   ' + pm.environment.get("accessTokenExpiry"));
    }
    
    const siaDesiredPostRequest = {

url: ‘https://iam.stage1.bluemix.net/identity/token’,
method: ‘POST’,
header: {
‘Accept’: ‘application/json’,
‘Content-Type’: ‘application/x-www-form-urlencoded’

  },
  body: {
      mode: 'urlencoded',
      urlencoded: [
        {key: "grant_type", value: "urn:ibm:params:oauth:grant-type:iam-authz"},
        {key: "desired_iam_id", value: "crn-crn:v1:bluemix:public:siapoc::a/73be9f58fe97adebbf9fe13eeea2ebe4:instance12345::"},
        {key: "Accept", value: "application/json"},
        {key: "Content-Type", value: "application/x-www-form-urlencoded"},
        {key: "access_token", value: pm.environment.get("sia_access_token")},
    ]
  }

};

    pm.sendRequest(siaDesiredPostRequest, function (err,siaDesiredPostres) {
console.log(err ? err : siaDesiredPostres.json());
    if (err === null) {
        
        var responseJson1 = siaDesiredPostres.json();
         pm.environment.set('going to set sia_desired_token *****\n', responseJson1.access_token);
        pm.environment.set("sia_desired_token",responseJson1.access_token);
        console.log('sia_desired_token' + pm.environment.get("sia_desired_token"));
        
        
    }
});
    
});

}

Looks like it is not recognizing the environment variables !
Appreciate your response
Tx
K.thulsi

@krishnandoss08 Please set the current value of the environment via the UI and try again. Be advised that it’s time consuming to triage and debug an apparent issue with full scripts you have written for your exact use case. If you could provide a simple collection just highlighting the environment issue you are facing, it’ll help us triage and get back to you faster.

Exactly what I was looking for!
I was trying to set up some variables in pre-request script in a collection and was puzzled that after execution even though the value was seen as set up but it was not shown when I was running the script and logging the value. Above solution made it work like a breeze. Thanks for posting :).