How to store a JSON in a variable and use it in the request body?

Hi,

I want to run a collection with specific test data, but restore the data from before my collection run afterwards.

My idea to achieve this is so far:

  1. Execute a GET request to retrieve the currently available data. Format: JSON
  2. Store that data in an environmentvariable
  3. Run collection that includes overriding the original data with PUT request containing my test data.
  4. Restore the original data from the environmentvariable

However this doesn’t seem to work.

Approach #1:
I used the code from a tutorial to store the data:

let response = pm.response.json();
let savedData = response;
pm.environment.set(“savedData”, savedData );

I checked data saved in the environment variable and it looks fine.

But I cannot pass the data to the body. I tried this in the body:

{{“savedData”}}

Approach #2:
I only stored the values of the data, but not the whole JSON:

let response = pm.response.json();
let savedData = response.values;
pm.environment.set(“savedData”, savedData );

And then trying this in the body:

{
“myData” : [{{“savedData”}}]
}

Doesn’t work either.

Any idea how to solve this problem?

2 Likes

@Myxlplyx

Try {{savedData}} instead of {{"savedData"}}. :cowboy_hat_face:

Thanks for your answer!

However if I try:
{
“myData”: [{{savedData}}]
}

I get the following error message:

Can not deserialize instance of com.xxx.xxx.xxx.xxx.xx.xxx.SavedData out of START_ARRAY token
at [Source: io.undertow.servlet.spec.ServletInputStreamImpl@39123303; line: 2, column: 24] (through reference chain: com.xxx.xxx.xxx.xxx.xx.xxx.xxxx.SavedDataMap[“savedData”]->java.util.ArrayList[0])

Any idea?

@Myxlplyx - So to solve your problem.

  1. In the test script of your GET request, you can put this down:
let response = pm.response.json(),
    savedData = JSON.stringify(response);

pm.environment.set("savedData", savedData);

You need to store the data in stringified format.

  1. In the body of the requests where you want to use this savedData you can simply put it like so:
    Make the body as ‘Raw’ and the type as ‘JSON’:

image

Put the following as the raw data:

{
   "myData": [{{savedData}}]
}

Run the request and you can see the following in the Postman Console

4 Likes

Hi sivcan,
thanks for your answer.

I also found a solution just a few hours ago before I saw your response.

This thread gave me the needed hint:

Here spefically this:

postman.setEnvironmentVariable(“deviceMapping”, responseBody);
//variables need to be strings

After understanding that responseBody stores the whole response body as a string, the solution was as easy as:

  1. In the GET request save the whole JSON response body to an environment variable:

postman.setEnvironmentVariable(“savedData”, responseBody);

  1. To pass the JSON data into a consecutive request just put the following as raw data:

{{savedData}}

That’s it :slight_smile:

@sivcan, thank you for the clarity here. I couldn’t find this info anywhere else!

I have a response of a API which looks like this on a GET - GET on API1
[
{
“id”: “emp1”,
“name”: suresh,
“address”: zxr street,
“zip”: 92111,
“city”: “fresno”,
“notes”: “employee of month”

},
{
	"id": "emp2",
    "name": rakesh,
    "address": zxry street,
    "zip": 92122,
    "city": "bakersfield",
    "notes": "hired recently",
}

]

I would like to extract only the city and provided it as a parameter to API 2
API 2 - companies/Co123/employees/3333?city={{cities}}

can anyone please guide me.

1 Like

The piece of code below will take the first city. If your result is a list:

pm.environment.set("CityId", pm.response.json()[0].city); or
pm.environment.set("CityId", pm.response.json().city); if is just one result.

Then use this variable in your request this way:

API 2 - companies/Co123/employees/3333?city={**{CityId}**}

However, if you want save all cities, you can use push() and pop() methods to append the results in a list and them iterate in other requests.

I’m kinda new here too, but I often do that way!

:sweat_smile:

1 Like

thanks sandokhan. Thats exactly the difficultly am having.
Do you have an example for multiple results to be chained to the next API?

its straight forward with one city . I am looking for multiple cities going in as input to the next API

1 Like

I’m here to fight the scope pollution fight :triumph:

If you don’t want to pollute your environment, please use collection variables when sharing data between requests in a collection! It’s the exact same thing but just pm.collectionVariables.set() instead of pm.environment.set()

1 Like

In the first request, on test I’ll put this code:

let Cities = JSON.parse(responseBody),
CityIds = _.map(body, (city) => city.id);

// Store all the Cities Ids in the environment variable
pm.environment.set('CityIdsList', JSON.stringify(CityIds));

// Store the next index of the array for City ids
pm.environment.set('nextIndex', 0);

// Store the active City ID 
pm.environment.set('activeCityId', CityIds[0]);

Then, on the second request I’ll use this one:

let CityIds = JSON.parse(pm.environment.get('CityIdsList')),
    nextIndex = parseInt(pm.environment.get('nextIndex')) + 1;

if (CityIds.length === nextIndex) {
    pm.environment.set('nextIndex', 0);
    pm.environment.set('activeCityId', CityIds[0]);

    postman.setNextRequest(null);
} else {
    let activeRODID = CityIds[nextIndex];
    pm.environment.set('nextIndex', nextIndex);
    pm.environment.set('activeCityId', activeCityId);
    postman.setNextRequest("Second Request");
}

Perhaps there is a more efficient way to do it, but this will work.

Hi @sivcan,
Is it possible to add Variable in the Pre-request script as well?
I want to add a variable for the URL parameter in the below pre-request script.

(Ex. http://dummy.restapiexample.com/api/v1/create)

pm.sendRequest({
url: “{{want to add variabl here}}/api/v1/create”,
method: ‘POST’,
header: ‘Content-Type:application/json’,
body: {
mode: ‘raw’,
raw: JSON.stringify({
“username”: “abc”,
“password”:"***"
})
}
},
function (err, response) {
if (response){
pm.environment.set(“value”, response.json().object.object);
}
});

Thanks for your time.

What you can do is make your entire request URL itself a variable, let’s say {{requestUrl}}

And then in your pre-request script, you can do something like this:

let baseRequestUrl = 'https://dummy.restapi.com/v1';

if (someCondition) {
  baseRquestUrl += '/create';
}
else {
  baseRequestUrl += '/update';
}

pm.variables.set('requestUrl', baseRequestUrl);

hi sivican,
is it possible to store request json in some variable and set the variable in response Body for mock responses with example

is it possible to store request json in some variable and set the variable in response Body for mock responses with example
i have req the that req or few of params i want to send in response(mocking response with example)

Yes it’s very much possible if you use environment variables.
While creating a mock you can choose the environment from the dropdown, and now keep storing your response JSON to this environment variable (remember to stringify it).

For eg: In your request you can do something like this:

let mockResponse = JSON.stringify(pm.response.json());
pm.environment.set('mockResponse', mockResponse);

And in your response body (make sure it’s type: raw) of the example you’ve to write something like this:

{{mockResponse}}

This variable will be resolved using the environment variable’s value every time you call it.

1 Like

thanks sivcan
i have tried the below mentioned link my question ways but not working(i didn’t used any environment while mocking)


please let know what i am dng wrong

I just tried the way you told below is prescipt

   var authorization = pm.request.headers.get("Authorization")
    if(authorization != "" && authorization != null)

    {   

        pm.environment.set("authorization", authorization);

        console.log(authorization)

    }

example response body wrote like below:
{{authorization}}

when run the request i am getting 200 response code but the response body not getting any thing


please find screenshot of same

@cdxcz Ah, looking at the screenshot now I got it. I misunderstood your query, what now I understand is that you want to call the mock with some response, and the response of this mock should contain the authorization that you’ve set right?

Alright, so for that to work you can have 2 approaches but the common part remains the same:
Common (Mandatory step):
Create a new mock with an environment associated (the mock will use this environment to resolve the variable from, otherwise it won’t work).

Approach 1: (Note: This will not work in the collection runner)

  1. Create a new request let’s say ‘Req 1’ (with a dummy URL such as google.com) in which you set this environment variable.
  2. Create a new request let’s say ‘Req 2’ which contains your mock URL, now call this mock URL and you’ll see the mock will resolve the variable value from the environment.
    => First hit “Send” on the “Req 1” and then hit “Send” for “Req 2”.

Approach 2: (More advanced and complicated, but will work in collection runner/monitor and just using a single request)

  1. You’d have to use the Postman API. Grab an API key to use the Postman API and see the section in the documentation around updating an environment.
  2. Use the pm.sendRequest function from your Pre-request Script to update the environment as soon as you run the request with the authorization header.

Using this approach, first, the environment will be updated by the Postman API in the cloud before the request is actually executed, and after that when the request is executed and hits the mock server of Postman in the cloud, the mock server will be able to resolve the updated environment value and thus return you the expected response. :slight_smile:

1 Like

thanks @sivcan. i will try this approach