Newbie Interrogating array response question

Hi all, apologies for what is probably a basic (and often asked) question but I can’t find a specific answer.

I have an API method which displays a string as part of the response containing 2 or more results e.g.;

“Object”: {
“value1”: {
“item1”,
“item2”,
“item3”: [
{
“result1”: “pink”,
“result2”: “orange”
},
{
“result1”: “brown”,
“result2”: “green”
}
]
},
“value2”: {
“item1”,
“item2”,
“item3”: [
{
“result1”: “black”,
“result2”: “orange”
},
{
“result1”: “purple”,
“result2”: “blue”
}

If I want to check if value2 contains orange, it’s easy enough to check if it exists using

const response = pm.response.json();
pm.expect(pm.response.text()).to.include(‘orange’);

which works fine but of course orange is included in value1

So what would the test be to target a specific part of the string response ?

i.e. does value2 contain orange

Thanks in advance

const response = pm.response.json();
pm.expect(pm.response.text()).to.include(‘orange’);

You parse the response to JSON on the first line, but then parse it again to text on the second line.
Which means the first line is doing nothing (unless you have other code using it).

However, you need to assert against the Json response, which should allow you to target the elements in various ways.

Can you please re-post your example response using the pre-formatted text, so everything gets aligned correctly.

It looks like you have multiple values in your response.

It looks like your JSON has multiple records, and item3 which seems to contain your results is an array.

Which one do you want to assert against? Is it always value2 → item3 → result2 (or can Orange be in any of the results for a particular item?)

Thanks for your reply, yes, there are other tests using the original ‘parse’.

Apologies, didn’t explain it correctly, not sure why it didn’t align properly, it looked right before I submitted :slight_smile: I’ve amended it but this is the gist of it

{
    "Object": {
        "value1": {
            "item": "item1",
            "colours": [
                {
                    "result1": "pink",
                    "result2": "orange"
                },
                {
                    "result1": "blue",
                    "result2": "brown"
                }
            ]
        },
        "value2": {
            "item": "item2",
            "colours": [
                 {
                    "result1": "black",
                    "result2": "orange"
                },
                {
                    "result1": "green",
                    "result2": "purple"
                }
            ]
        }
    }
}

So I need to be able to say, for example, does value 2 contain orange.

Hope that makes sense :slight_smile:

Ok, that JSON is horrible to search.

Colours is an array of JavaScript objects, and within each object the results are named differently. If each object had an “array” of results. You could be able to pinpoint the element using the JavaScript find function.

This is not easy to search without going through the entire array. (Which is a lot of code considering the complex nature of this JSON response).

So I’ve gone back to your original method which is to search it as a string.

I’ve done this by parsing the response, then extracting value2.colours before converting it back into a string using JSON.stringify to do the comparison\search.

I’ve then searched using the indexOf() function which will return the index number of the element, or -1 if its not found. Therefore to work out if “orange” was found. You just need to ensure the response was not -1.

response = pm.response.json()

let colours = response.Object.value2.colours

pm.test("value2 - colours include orange", () => {
    let search = JSON.stringify(colours).indexOf("orange");
    // indexOf() returns -1 if the element is not found
    pm.expect(search).to.be.above(-1);
});

pm.test("value2 - colours include blue", () => {
    let search = JSON.stringify(colours).indexOf("blue");
    // indexOf() returns -1 if the element is not found
    pm.expect(search).to.be.above(-1);
});

This is another option, but I’m not convinced its any better than the previous response.

It’s using a helper function to bring back the JavaScript object that contains Orange.

Paired with Object.values to just return the values.

This means you can then do a simple test on includes("orange)

I guess if anything it helps with readability.

response = pm.response.json()

let colours = response.Object.value2.colours

//http://techslides.com/how-to-parse-and-search-json-in-javascript
//return an array of objects according to key, value, or key and value matching
function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));    
        } else 
        //if key matches and value matches or if key matches and value is not passed (eliminating the case where key matches but passed value does not)
        if (i == key && obj[i] == val || i == key && val == '') { //
            objects.push(obj);
        } else if (obj[i] == val && key == ''){
            //only add if the object is not already in the array
            if (objects.lastIndexOf(obj) == -1){
                objects.push(obj);
            }
        }
    }
    return objects;
}

pm.test("value - colours include orange V2", () => {
    let search = (Object.values(getObjects(colours,"", "orange")[0]));
    pm.expect(search).to.include("orange");
});

Credit to How to parse and search JSON in JavaScript | TechSlides for the function. There are three functions on that page for searching objects and arrays which I would recommend anyone to review if having issues searching and returning elements due to complex responses\JSON.

Cheers Mike, I’ll have a play around, as you say, it’s messy for what you’d think should be reasonably straight forward.

HNY :slight_smile: