How to compare 2 response json using recursive function in postman - javascript

I want to compare 2 json and return error message for which object or value is not match
For example:
json1 = {
"id": 1,
"product": {
"productId": "456",
"product_detail": [
{
"name": {
"value": 1
}
},
{
"name": {
"value": 2
}
}
]
}
}
json2 = {
"id": 1,
"product": {
"productId": "123",
"product_info": [
{
"name": [{
"value": 3,
}
},
{
"name": {
"value": 4
}
}
]
}
}
I was using try / catch on each object and value, however, it is complicated process to const each propriety. Therefore, i am looking for another way to do the checking
My expected error message result should return all object / value is not matching in test result:
Failed - json2 > product_info propriety not matching with json
Failed - json2 > product.product_detail.name[0].value : 3 not equal with json1 > product.product_detail.name[0].value :1
Failed - json2 > product.product_detail.name[1].value : 4 not equal with json1 > product.product_detail.name[1].value :2
If there are no error found > return message pass

are you sure you need recursion for that?
Checkout lodash isEqual function: https://lodash.com/docs/#isEqual

Related

TypeError: Cannot read properties of undefined (reading 'product-1')

So I am trying to display JSON data in my React.js project, but I am getting an error that I can't figure out. I've spent 2 days trying to figure it out, but had no luck
The JSON data: (filename: products.json)
{
"product-1": [
{
"id": 1,
"name": "product-1",
}
],
"product-2": [
{
"id": 2,
"name": "product-2",
}
],
"product-3": [
{
"id": 3,
"name": "product-3",
}
]
}
My javascript:
const productsData = Object.keys(backendData).map(key => {
return {
[key]: backendData[key]
}
})
console.log(productsData[0].products["product-1"][0].id)
error:
Log of backEndData:
Because productsData will return you array like this:
[
{ "product-1": [
{
"id": 1,
"name": "product-1",
}
]},
{"product-2": [
{
"id": 2,
"name": "product-2",
}
]}, ....
]
Meaning this is array of objects, where each object have one key-value pair, where key is name and value is an array.
If you want to access id then you should do like this:
productsData[0]["product-1"][0].id
UPDATED AFTER UPDATE OF OP
Since your backendData value does not match product.json, I will ignore that product.json and write you the solution which will work for the value of backendData you just provided.
const productsData = backendData.products;
const id = productsData[0]["product-1"][0].id;

Save a specific variable from a postman array

I have a postman json response and within the array the position of a specific variable changes. Based on my response below i need to write a test to loop through the response the first sighting of optionLabel with value "2 Pax Min".
Save its "id" i.e BBBB in the environment variable
I have tried this
var jsonData = JSON.parse(responseBody);
jsonData[[0].optionSet.options].forEach(function(arroption) {
if (arroption.optionLabel === '2 Pax Min') {
pm.environment.set("pax", JSON.stringify(arroption.id));
}
});
My Response
[
{
"id": "",
"date": "2019-08-21",
"optionSet": {
"optionSetLabel": "Options",
"options": [
{
"id": "A",
"optionLabel": "QUAD Rm"
},
{
"id": "AA",
"optionLabel": "QUAD Rm with post Accom"
},
{
"id": "AAA",
"optionLabel": "Rm 3 Pax Min"
},
{
"id": "AAAA",
"optionLabel": "4 Pax Min"
}
]
}
},
{
"id": "",
"date": "2019-08-22",
"optionSet": {
"optionSetLabel": "Options",
"options": [
{
"id": "B",
"optionLabel": "QUAD Rm"
},
{
"id": "BB",
"optionLabel": "QUAD Rm with post Accom"
},
{
"id": "BBB",
"optionLabel": "SGL Rm with post Accom"
},
{
"id": "BBBB",
"optionLabel": "2 Pax Min"
}
]
}
}
]
My end result is i want to save the id "BBBB" in the environment variable
You have a braket problem here jsonData[[0].optionSet.options].
Maybe you wanted to do something like jsonData[0].optionSet.options or jsonData[1].optionSet.options
Here this code should do what you want
for (let data of jsonData) {
for (let option of data.optionSet.options) {
if (option.optionLabel === '2 Pax Min') {
pm.environment.set("pax", JSON.stringify(option.id));
}
}
}
Same with forEach rather than for loop
jsonData.forEach(function(data) {
data.optionSet.options.forEach(function(arroption) {
if (arroption.optionLabel === '2 Pax Min') {
pm.environment.set("pax", JSON.stringify(arroption.id));
}
})
})
Mickael's answer should be the accepted solution (I upvoted it) but I just wanted to offer the same thing done with Lodash, which is built-in to Postman.
_.each(pm.response.json(), (data) => {
_.each(data.optionSet.options, (option) => {
if (option.optionLabel === '2 Pax Min') {
pm.environment.set("pax", option.id);
}
})
})
I see lots of answers that do this var jsonData = JSON.parse(responseBody); to parse the response body but it's the same as just using the newer pm.* API function pm.response.json() to do the same thing.
https://learning.getpostman.com/docs/postman/scripts/postman_sandbox_api_reference/

Add json Elements and values to Multiple json objects

I want combine a JSON object to an ARRAY.
I would like retrieve data from keys finded on var product, and combine score finded to a new variable ( combined results )
combinedresults is what I need. I absolutely don't know how to do this
var product = {
"presentation": 3,
"imgmax": http://test.com/img.jpg,
"puissance": 5,
"efficacite": 4,
"description": "This product is awesome but i need to combine JSON results"
}
var array = [
{
"caracname": "presentation",
"name": "Présentation"
},
{
"caracname": "efficacite",
"name": "Efficacité"
},
{
"caracnam": "puissance",
"name": "Puissance"
}
]
var combinedresults = [
{
"caracname": "presentation",
"name": "Présentation",
"score": 3
},
{
"caracname": "efficacite",
"name": "Efficacité",
"score": 4
},
{
"caracnam": "puissance",
"name": "Puissance",
"score": 5
}
]
Iterate through each item of the array, if the product object contains a key that matches the current items caracname, add it's value as a score.
See below:
var product = {
"presentation": 3,
"imgmax": "http://test.com/img.jpg",
"puissance": 5,
"efficacite": 4,
"description": "This product is awesome but i need to combine JSON results"
}
var array = [
{
"caracname": "presentation",
"name": "Présentation"
},
{
"caracname": "efficacite",
"name": "Efficacité"
},
{
"caracname": "puissance",
"name": "Puissance"
}
]
array.forEach(function(item) {
if (product[item.caracname]) {
item.score = product[item.caracname];
}
});
console.log(array);
Simply map over your current array, extending every object with the score attribute.
array.map(obj => ({...obj, score: product[obj.caracname]}));
If you are not familiar, consider having a look at the spread operator;

How to iterate through deeply nested objects inside of a JSON?

I know there are plenty of questions about iterating through JSON objects but I haven't found one that quite relates to my exact problem. This is the JSON that I'm trying to iterate through:
psinsights = {
"kind": "pagespeedonline#result",
"id": "/speed/pagespeed",
"responseCode": 200,
"title": "PageSpeed Home",
"score": 90,
"pageStats": {
"numberResources": 22,
"numberHosts": 7,
"totalRequestBytes": "2761",
"numberStaticResources": 16,
"htmlResponseBytes": "91981",
"cssResponseBytes": "37728",
"imageResponseBytes": "13909",
"javascriptResponseBytes": "247214",
"otherResponseBytes": "8804",
"numberJsResources": 6,
"numberCssResources": 2
},
"formattedResults": {
"locale": "en_US",
"ruleResults": {
"AvoidBadRequests": {
"localizedRuleName": "Avoid bad requests",
"ruleImpact": 0.0
},
"MinifyJavaScript": {
"localizedRuleName": "Minify JavaScript",
"ruleImpact": 0.1417,
"urlBlocks": [
{
"header": {
"format": "Minifying the following JavaScript resources could reduce their size by $1 ($2% reduction).",
"args": [
{
"type": "BYTES",
"value": "1.3KiB"
},
{
"type": "INT_LITERAL",
"value": "0"
}
]
},
"urls": [
{
"result": {
"format": "Minifying $1 could save $2 ($3% reduction).",
"args": [
{
"type": "URL",
"value": "http://code.google.com/js/codesite_tail.pack.04102009.js"
},
{
"type": "BYTES",
"value": "717B"
},
{
"type": "INT_LITERAL",
"value": "1"
}
]
}
},
{
"result": {
"format": "Minifying $1 could save $2 ($3% reduction).",
"args": [
{
"type": "URL",
"value": "http://www.gmodules.com/ig/proxy?url\u003dhttp%3A%2F%2Fjqueryjs.googlecode.com%2Ffiles%2Fjquery-1.2.6.min.js"
},
{
"type": "BYTES",
"value": "258B"
},
{
"type": "INT_LITERAL",
"value": "0"
}
]
}
}
]
}
]
},
"SpriteImages": {
"localizedRuleName": "Combine images into CSS sprites",
"ruleImpact": 0.0
}
}
},
"version": {
"major": 1,
"minor": 11
}
};
Now, I'm trying to write a function that iterates through all of the ruleResults objects and returns an array of the localizedRuleName properties. According to the JSON, ruleResults has three member objects (AvoidBadRequests, MinifyJavaScript, and SpriteImages). Each of these has a localizedRuleName property I'm trying to access, but when I print out my array, it's blank. Here's how I've written my function:
function ruleList(results) {
var ruleArray = [];
for(var ruleName in results.formattedResults.ruleResults){
ruleArray[counter] = results.formattedResults.ruleResults[ruleName].localizedRuleName;
}
return ruleArray;
}
console.log(ruleList(psinsights));
Can you guys help me get on the right track? I used basically this same method to iterate through the pageStats of the JSON and it worked perfectly. I'm not sure why I can't get it to work with these deeper nested objects and properties.
your problem is not your iteration, but your undefined variable "counter".
Instead of using a counter can use the "push" function:
function ruleList(results) {
var ruleArray = [];
for(var ruleName in results.formattedResults.ruleResults){
ruleArray.push(results.formattedResults.ruleResults[ruleName].localizedRuleName);
}
return ruleArray;
}
fiddle: https://jsfiddle.net/fo9h56gh/
Hope this helps.
you're probably getting a javascript error since counter is not defined. you can try this:
function ruleList(results) {
var ruleArray = [];
var counter = 0;
for(var ruleName in results.formattedResults.ruleResults){
ruleArray[counter] = results.formattedResults.ruleResults[ruleName].localizedRuleName;
counter++;
}
return ruleArray;
}

Search deep nested

I am working on a solution where I need to search for an element in a deeply nested JSON by its id. I have been advised to use underscore.js which I am pretty new to.
After reading the documentation http://underscorejs.org/#find , I tried to implement the solution using find, filter and findWhere.
Here is what I tried using find :
var test = {
"menuInputRequestId": 1,
"catalog":[
{
"uid": 1,
"name": "Pizza",
"desc": "Italian cuisine",
"products": [
{
"uid": 3,
"name": "Devilled chicken",
"desc": "chicken pizza",
"prices":[
{
"uid": 7,
"name": "regular",
"price": "$10"
},
{
"uid": 8,
"name": "large",
"price": "$12"
}
]
}
]
},
{
"uid": 2,
"name": "Pasta",
"desc": "Italian cuisine pasta",
"products": [
{
"uid": 4,
"name": "Lasagne",
"desc": "chicken lasage",
"prices":[
{
"uid": 9,
"name": "small",
"price": "$10"
},
{
"uid": 10,
"name": "large",
"price": "$15"
}
]
},
{
"uid": 5,
"name": "Pasta",
"desc": "chicken pasta",
"prices":[
{
"uid": 11,
"name": "small",
"price": "$8"
},
{
"uid": 12,
"name": "large",
"price": "$12"
}
]
}
]
}
]
};
var x = _.find(test, function (item) {
return item.catalog && item.catalog.uid == 1;
});
And a Fiddle http://jsfiddle.net/8hmz0760/
The issue I faced is that these functions check the top level of the structure and not the nested properties thus returning undefined. I tried to use item.catalog && item.catalog.uid == 1; logic as suggested in a similar question Underscore.js - filtering in a nested Json but failed.
How can I find an item by value by searching the whole deeply nested structure?
EDIT:
The following code is the latest i tried. The issue in that is that it directly traverses to prices nested object and tries to find the value. But my requirement is to search for the value in all the layers of the JSON.
var x = _.filter(test, function(evt) {
return _.any(evt.items, function(itm){
return _.any(itm.outcomes, function(prc) {
return prc.uid === 1 ;
});
});
});
Here's a solution which creates an object where the keys are the uids:
var catalogues = test.catalog;
var products = _.flatten(_.pluck(catalogues, 'products'));
var prices = _.flatten(_.pluck(products, 'prices'));
var ids = _.reduce(catalogues.concat(products,prices), function(memo, value){
memo[value.uid] = value;
return memo;
}, {});
var itemWithUid2 = ids[2]
var itemWithUid12 = ids[12]
I dont use underscore.js but you can use this instead
function isArray(what) {
return Object.prototype.toString.call(what) === '[object Array]';
}
function find(json,key,value){
var result = [];
for (var property in json)
{
//console.log(property);
if (json.hasOwnProperty(property)) {
if( property == key && json[property] == value)
{
result.push(json);
}
if( isArray(json[property]))
{
for(var child in json[property])
{
//console.log(json[property][child]);
var res = find(json[property][child],key,value);
if(res.length >= 1 ){
result.push(res);}
}
}
}
}
return result;
}
console.log(find(test,"uid",4));

Categories

Resources