10

Currently using the latest version of Postman: 6.7.4 (Latest)

I'm trying to get a value out of a JSON response body and store it in an environment variable BUT the value 'username' should be equal to my preferred username.

Normally I would extract a value like this:

var jsonData = pm.response.json();
pm.environment.set("useridToken", jsonData.Customers[0].userid);

This would give me the first item in the list but I do not wish to obtain the first nor the second item from the list. I wish to obtain the userid where username EQUAL "Billy" for example.

Output of the body response:

{
"Customers": [
    {
        "id": 24,
        "userid": 73063,
        "username": "BOB",
        "firstname": "BOB",
        "lastname": "LASTNAME
    },
    {
        "id": 25,
        "userid": 73139,
        "username": "Billy",
        "firstname": "Billy",
        "lastname": "lasty"
    }
   ]
}

Any tips?

I remember in SoapUI it was like this:

$.channels[?(@.is_archived=='false')].id[0]

I guess it's not possible to do this in JS in Postman?

Decypher
  • 690
  • 1
  • 8
  • 30
  • 4
    [`Array.find()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) (this question has nothing to do with postman or JSON btw, it's about finding a specific element in an array) –  Feb 27 '19 at 09:22
  • 1
    Possible duplicate of [How to find first element of array matching a boolean condition in JavaScript?](https://stackoverflow.com/questions/10457264/how-to-find-first-element-of-array-matching-a-boolean-condition-in-javascript) – vahdet Feb 27 '19 at 09:25

8 Answers8

13

You can use: Array.prototype.find():

const data = {
  "Customers": [{
      "id": 24,
      "userid": 73063,
      "username": "BOB",
      "firstname": "BOB",
      "lastname": "LASTNAME"
    },
    {
      "id": 25,
      "userid": 73139,
      "username": "Billy",
      "firstname": "Billy",
      "lastname": "lasty"
    }
  ]
}

const user = data.Customers.find(u => u.username === 'Billy')
const userid = user ? user.userid : 'not found'

console.log(user)
console.log(userid)
Yosvel Quintero
  • 18,669
  • 5
  • 37
  • 46
4

find() as another answer points out is the best solution here, but if the username is not unique and you want an array of users where username is 'Billy' then use filter()

const jsonData = {
  "Customers": [{
      "id": 24,
      "userid": 73063,
      "username": "BOB",
      "firstname": "BOB",
      "lastname": "LASTNAME"
    },
    {
      "id": 25,
      "userid": 73139,
      "username": "Billy",
      "firstname": "Billy",
      "lastname": "lasty"
    }
  ]
}
console.log(jsonData.Customers.filter(c => c.username === 'Billy'))
holydragon
  • 6,158
  • 6
  • 39
  • 62
  • Notice that `Array.prototype.filter()` is not performant because it will filter the entire `array`.. And you need to find only the first one because `username` is unique – Yosvel Quintero Feb 27 '19 at 09:35
  • @YosvelQuintero I already stated that `.find()` is better, and use `.filter()` when username is not unique. Moreover, you are assuming that the username is unique since the question does not provide that information. – holydragon Feb 27 '19 at 09:51
4

In Postnam test script, you can use some Javascript features. In your case, too many way to do. I will show you how to solve your case with Array.find function:

var jsonData = pm.response.json();
var user = jsonData.Customers.find(function(user) {
    return user.username === 'Billy';
    // OR you could config username in postman env
    // return user.username === pm.variables.get("username_to_find"); 
});
pm.environment.set("useridToken", user.userid);
hoangdv
  • 15,138
  • 4
  • 27
  • 48
1

Your userid can also be obtained using filter as follows -

const data = {
  "Customers": [{
      "id": 24,
      "userid": 73063,
      "username": "BOB",
      "firstname": "BOB",
      "lastname": "LASTNAME"
    },
    {
      "id": 25,
      "userid": 73139,
      "username": "Billy",
      "firstname": "Billy",
      "lastname": "lasty"
    }
  ]
};
const username = 'Billy';
const user = data.Customers.filter(obj => obj.username.toLowerCase() === username.toLowerCase())[0];
const userid = user ? user['userid'] : null;

console.log(userid);

Note: .toLowerCase() is optional here, you may use it depending on your condition.

Then you could simply set it as -

pm.environment.set("useridToken", userid);
Tushar Walzade
  • 3,737
  • 4
  • 33
  • 56
1

This answer is inspired by the other answer that outputs an array. 1

It is not clearly stated by the original poster whether the desired output should be a single userid (presumably the first occurence?) - or an array containing all userid:s matching "Billy".

This answer shows a solution to the latter case by using Lodash.

const jsonData = {
  Customers: [{
    userid: 73063,
    username: 'BOB'
  }, {
    userid: 73138,
    username: 'Billy'
  }, {
    userid: 74139,
    username: 'Billy'
  }]
};

const userIds = [];
_.forEach(_.filter(jsonData.Customers, c => c.username === 'Billy'),
  item => { userIds.push(item.userid); });
console.log(userIds);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.js"></script>

1 That answer is quite helpful as it hints how to filter out the relevant objects of the Customers array. However, the original poster wants (an array of) the userid(s) which is a number, and not an an array of objects that contains the userid:s. This is how my answer here is different.

Henke
  • 4,445
  • 3
  • 31
  • 44
  • this was actually the best solution for me as the .find syntax was not coming up as an option only the .filter was working. thanks @henke – Laser Hawk Dec 10 '21 at 03:17
0

Try this

const userid = data.Customers.find(u => u.username === 'Billy') || 'not found';
0

Repeating the currently highest voted answer, slightly modified.
Also adding a solution inspired by the other Lodash answer.1

const jsonData = {
  Customers: [{
    id: 24,
    userid: 73063,
    username: 'BOB',
    firstname: 'BOB',
    lastname: 'LASTNAME'
  }, {
    id: 25,
    userid: 73139,
    username: 'Billy',
    firstname: 'Billy',
    lastname: 'lasty'
  }]};
for (const i in jsonData.Customers) {
  console.log('userid of customer['+i+']: '+jsonData.Customers[i].userid);
}
const userId_UsingFind = (name) => {
  const user = jsonData.Customers.find(item => item.username === name);
  return user ? user.userid : user;
};
console.log('Using .find(), userid of "Billy": '+userId_UsingFind('Billy'));
console.log('Using .find(), userid of "Joe": '+userId_UsingFind('Joe'));

const userId_Native = (name) => {
  for (const i in jsonData.Customers) {
    if (jsonData.Customers[i].username === name) {
      return jsonData.Customers[i].userid;
    }
  }
};
console.log('Native loop, userid of "Billy": '+userId_Native('Billy'));
console.log('Native loop, userid of "Joe": '+userId_Native('Joe'));

As the code shows, the solution using .find() is both short and elegant.


1 Assuming the desired outcome is the userid of the first Billy. To retrieve an array of userid:s for all occurrences ofBilly, see the answer that returns an array of userid:s .

Henke
  • 4,445
  • 3
  • 31
  • 44
0

This answer shows a solution using the JavaScript library Lodash.
This is not meant as a recommendation, but merely to prove that it is possible to use Lodash.
It is inspired by the other lodash answer.1

const jsonData = {
  Customers: [{
    id: 24,
    userid: 73063,
    username: 'BOB',
    firstname: 'BOB',
    lastname: 'LASTNAME'
  }, {
    id: 25,
    userid: 73139,
    username: 'Billy',
    firstname: 'Billy',
    lastname: 'lasty'
  }]
};

const userId_Lodash = (name) => {
  let userId;
  _.forEach(jsonData.Customers, (item) => {
    if (item.username === name) { userId = item.userid; }
  });
  return userId;
};
console.log('Lodash loop, userid of "Billy": ' + userId_Lodash('Billy'));
console.log('Lodash loop, userid of "Dave": ' + userId_Lodash('Dave'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.19/lodash.js"></script>

For the question at hand, I don't see any particular reason to use the Lodash library.
But in other examples it could make all the more sense.


1 The posted question does not state whether the desired outcome is the first userid matching Billy, or all such userid:s. This answer gives the first hit.

Henke
  • 4,445
  • 3
  • 31
  • 44