Big Json parsing in cypress, jsonPath usage - javascript

I'm new to cypress and I face a problem when trying to work with json responses. I am getting json with units structure(tree structure) and I need to get all the names from it.
I tried to use jsonpath dependenc and parse json using jp.query, but it doesn't works:
cy.request(*some request*).its('body').then((body) => {
let units = jp.query(body, "$..[?(#.type=='PROJECT')].name");
})
I'm getting obj needs to be an object Assertion error here
How to fix this or maybe there are any other ways to parse json in cypress?
JSON Sample:
[
{
"id": 2,
"name": "Solar",
"children": [
{
"id": 3,
"name": "Earth",
"children": [
{
"id": 4,
"name": "Moon",
"type": "STREAM",
"active": true
}
],
"type": "PROJECT",
"active": true
},
{
"id": 5,
"name": "Jupiter",
"children": [
{
"id": 6,
"name": "Io",
"type": "STREAM",
"active": true
},
{
"id": 7,
"name": "Ganymede",
"type": "STREAM",
"active": true
}
]},
],
"type": "PROGRAM",
"active": true
},
{
"id": 9,
"name": "Centaurus",
"children": [
{
"id": 10,
"name": "Alpha Centauri A",
"children": [
{
"id": 818,
"name": "Alpha Centauri Aa-2345",
"type": "STREAM",
"active": true
}
],
"type": "PROJECT",
"active": true
},
{
"id": 11,
"name": "Alpha Centauri B",
"children": [
{
"id": 12,
"name": "Alpha Centauri Bb",
"type": "STREAM",
"active": true
}
],
"type": "PROJECT",
"active": true
},
],
"type": "PROGRAM",
"active": true
}
]

add below 2 lines before jp.query()
body = JSON.stringify(body);
body = JSON.parse(body);

Depending on how the request/response is configured, you may have one of the following issues
response is a string
body is a string
there is no body
cy.request(*some request*)
.then(response => response.json())
.its('body')
.then(body => {
let units = jp.query(body, "$..[?(#.type=='PROJECT')].name");
})
or
cy.request(*some request*)
.its('body')
.then(body => body.json())
.then(body => {
let units = jp.query(body, "$..[?(#.type=='PROJECT')].name");
})
or
cy.request(*some request*)
.then(response => response.json())
.then(jsonObj => {
let units = jp.query(jsonObj, "$..[?(#.type=='PROJECT')].name");
})

Related

How to print huge number of items from the json array

This is my json format with that im displaying my array items like this.
If i have more items in my array mean how can i print that all using for loop or is there any method available to print all that items in an array?
{
"workers": [
{ "id": "5001", "type": "Basic" },
{ "id": "5002", "type": "Admin" },
{ "id": "5003", "type": "Basic" }
],
"clients": [
{ "id": "5004", "type": "Pro" },
{ "id": "5005", "type": "Basic" },
{ "id": "5006", "type": "Basic" },
{ "id": "5007", "type": "Pro" }
]
}
<script>
const api_url = "API URL";
async function get_data_from_api() {
const response = await fetch(api_url);
var data = await response.json();
var track = data["workers"][2]["id"];
document.getElementById('demo2').innerHTML = track ;
}
</script>
Reference:
JSON.stringify()
const o = {
"workers": [
{ "id": "5001", "type": "Basic" },
{ "id": "5002", "type": "Admin" },
{ "id": "5003", "type": "Basic" }
],
"clients": [
{ "id": "5004", "type": "Pro" },
{ "id": "5005", "type": "Basic" },
{ "id": "5006", "type": "Basic" },
{ "id": "5007", "type": "Pro" }
]
};
output.innerHTML = JSON.stringify(o, undefined, 2);
<pre id="output"></pre>

How to dynamically create and iterate Json Object inside a Json Array using Postman - Javascript

I have a payload like mentioned below :
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters": {
"batter": [
{
"id": "1001",
"type": "Regular"
},
{
"id": "1002",
"type": "Chocolate"
},
{
"id": "1003",
"type": "Blueberry"
},
{
"id": "1004",
"type": "Devil’sFood"
}
]
},
"topping": [
{
"id": "5001",
"type": "None"
},
{
"id": "5002",
"type": "Glazed"
},
{
"id": "5005",
"type": "Sugar"
},
{
"id": "5007",
"type": "PowderedSugar"
},
{
"id": "5006",
"type": "ChocolatewithSprinkles"
},
{
"id": "5003",
"type": "Chocolate"
},
{
"id": "5004",
"type": "Maple"
}
]
}
**I want to increment the json objects dynamically(it can be a duplicate as well) which is inside the array topping based on the array size. For example if mention the array size as topping[10] it is suppose to create a payload of 10 objects and push those 10 objects of similar type inside the array topping ** Is it possible to dynamically create json objects and post the request in postman??
Kind note : The size of the array should be parameterized. Please let me know.
Please find the image highlighted in green. I want to dynamically increase the payload(topping array size based on the index using postman
You could do this:
Tab Pre-request
let req = {
"id": "0001",
"type": "donut",
"topping": []
};
let numberOfTopping = 5;
for (let i = 0; i < numberOfTopping; i++) {
let toppingItem = {
"id": `${_.random(5001, 5010)}`,
"type": `${_.sample(["Glazed", "Sugar", "None"])}`
};
req.topping[i] = toppingItem;
}
pm.variables.set("req", JSON.stringify(req));
Tab body
Result
{
"id": "0001",
"type": "donut",
"topping": [
{
"id": "5006",
"type": "Glazed"
},
{
"id": "5001",
"type": "Sugar"
},
{
"id": "5006",
"type": "Glazed"
},
{
"id": "5006",
"type": "None"
},
{
"id": "5008",
"type": "Sugar"
}
]
}

How to loop through nested JSON and append in HTML DOM

I am trying to loop through a JSON and append it to HTML in a nested way. What I am trying to do is add a Header tag for the title of the object and have tags for the titles of items. Some objects might not have the items as empty too. I am guessing a nested loop is required and I've tried implementing it. The JSON looks like:
[
{
"id": 1,
"title": "Hello",
"url": "http://localhost:8000/login/notes/1/",
"description": "Hello nice",
"created_at": "2019-08-10T06:02:55.468315Z",
"created_by": "Dude",
"items": [
{
"id": 1,
"url": "http://localhost:8000/login/items/1/",
"title": "baby's toy",
"note": "http://localhost:8000/login/notes/1/"
},
{
"id": 2,
"url": "http://localhost:8000/login/items/2/",
"title": "baby's toy",
"note": "http://localhost:8000/login/notes/1/"
},
{
"id": 4,
"url": "http://localhost:8000/login/items/4/",
"title": "postman5",
"note": "http://localhost:8000/login/notes/1/"
}
]
},
{
"id": 2,
"title": "abc",
"url": "http://localhost:8000/login/notes/2/",
"description": "asad",
"created_at": "2019-08-10T15:23:53.074848Z",
"created_by": "dude2",
"items": [
{
"id": 5,
"url": "http://localhost:8000/login/items/5/",
"title": "Parrot Toy",
"note": "http://localhost:8000/login/notes/2/"
}
]
}]
I've tried
fetch('http://localhost:8000/login/notes/?format=json',{mode: 'cors'})
.then(response => response.json())
.then(data => {
var output='';
var final='';
var semif='';
var darif='';
for (var i in data) {
output+=i+'<h2>'+data[i].title +'</h2>'
for(j in data[i].items){
final+='<li>'+data[i].items[j].title+'</li>'
}
semif=output+final
}
document.getElementById('test').innerHTML=darif
});
HTML
<p id="test">
</p>
What I want to achieve is:
<h1>Hello</h1>
<h5>baby's toy</h5>
<h5>baby's toy</h5>
<h5>postman5</h5>
<h1>abc</h1>
<h5>parrot's toy</h5>
I strongly advise against doing lengthy string concatenations. Strings are immutable objects and they can put unnecessary burden on your system.
In addition, using map and join is much more elegant and easier to read.
const data = [
{
"id": 1,
"title": "Hello",
"url": "http://localhost:8000/login/notes/1/",
"description": "Hello nice",
"created_at": "2019-08-10T06:02:55.468315Z",
"created_by": "Dude",
"items": [
{
"id": 1,
"url": "http://localhost:8000/login/items/1/",
"title": "baby's toy",
"note": "http://localhost:8000/login/notes/1/"
},
{
"id": 2,
"url": "http://localhost:8000/login/items/2/",
"title": "baby's toy",
"note": "http://localhost:8000/login/notes/1/"
},
{
"id": 4,
"url": "http://localhost:8000/login/items/4/",
"title": "postman5",
"note": "http://localhost:8000/login/notes/1/"
}
]
},
{
"id": 2,
"title": "abc",
"url": "http://localhost:8000/login/notes/2/",
"description": "asad",
"created_at": "2019-08-10T15:23:53.074848Z",
"created_by": "dude2",
"items": [
{
"id": 5,
"url": "http://localhost:8000/login/items/5/",
"title": "Parrot Toy",
"note": "http://localhost:8000/login/notes/2/"
}
]
}]
const result = data.map(el => {
return `<h1>${el.title}</h1>` + el.items.map(el => `<h5>${el.title}</h5>`).join("")
}).join("")
console.log(result)
fetch('http://localhost:8000/login/notes/?format=json',{mode: 'cors'})
.then(response => response.json())
.then(data => {
var html = '';
data.forEach(listItem => {
const h1 = `<h1> ${listItem.title} </h1>`;
html+=h1;
listItem.items.forEach(item=> {
const h5 = `<h5> ${item.title} </h5>`;
html+=h5;
});
});
document.getElementById('test').innerHTML=html;
});
I think you may use it.

Need to get Name, Node Name and Phase Values from API

I am trying to get Name, Node Name and Phase values from JSON Data using JavaScript. Here is my JavaScript
<script>
$(document).ready(function () {
$.getJSON('http://ec2-3-82-117-70.compute-1.amazonaws.com:8080/api/v0/retrievePodStatus/default',
function (data) {
console.log(data)
document.body.append("Name: " + data.items[1].metadata.name);
// document.body.append(data.items[1].metadata.name);
// document.body.append(data.items[0].spec.nodeName);
});
});
</script>
I am just getting the name in here. Can someone please help me how to get Name, Node Name and Phase Values? find the below JSON as well.
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"annotations": {
"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu request for container external-dns"
},
"creationTimestamp": "2019-02-28T16:22:49Z",
"generateName": "external-dns-5d69b66646-",
"labels": {
"app": "external-dns",
"pod-template-hash": "1825622202"
},
"name": "external-dns-5d69b66646-pmxmd",
"namespace": "default",
"ownerReferences": [
{
"apiVersion": "extensions/v1beta1",
"blockOwnerDeletion": true,
"controller": true,
"kind": "ReplicaSet",
"name": "external-dns-5d69b66646",
"uid": "170d9260-3b75-11e9-abe2-0ec5819342ce"
}
],
"resourceVersion": "2984",
"selfLink": "/api/v1/namespaces/default/pods/external-dns-5d69b66646-pmxmd",
"uid": "170e1a0d-3b75-11e9-abe2-0ec5819342ce"
},
"spec": {
"containers": [
{
"args": [
"--source=service",
"--source=ingress",
"--provider=aws",
"--registry=txt",
"--txt-owner-id=qpair"
],
"image": "registry.opensource.zalan.do/teapot/external-dns:v0.4.2",
"imagePullPolicy": "IfNotPresent",
"name": "external-dns",
"resources": {
"requests": {
"cpu": "100m"
}
},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [
{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "default-token-rr546",
"readOnly": true
}
]
}
],
"dnsPolicy": "ClusterFirst",
"nodeName": "ip-172-20-39-147.ec2.internal",
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"serviceAccount": "default",
"serviceAccountName": "default",
"terminationGracePeriodSeconds": 30,
"tolerations": [
{
"effect": "NoExecute",
"key": "node.kubernetes.io/not-ready",
"operator": "Exists",
"tolerationSeconds": 300
},
{
"effect": "NoExecute",
"key": "node.kubernetes.io/unreachable",
"operator": "Exists",
"tolerationSeconds": 300
}
],
"volumes": [
{
"name": "default-token-rr546",
"secret": {
"defaultMode": 420,
"secretName": "default-token-rr546"
}
}
]
},
"status": {
"conditions": [
{
"lastProbeTime": null,
"lastTransitionTime": "2019-02-28T16:22:49Z",
"status": "True",
"type": "Initialized"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2019-02-28T16:22:58Z",
"status": "True",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2019-02-28T16:22:49Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [
{
"containerID": "docker://18b96317cf360d562fb3f849c6716c50a41a67a4dbc126164020531e1e4d84a9",
"image": "registry.opensource.zalan.do/teapot/external-dns:v0.4.2",
"imageID": "docker-pullable://registry.opensource.zalan.do/teapot/external-dns#sha256:d54b9eb8948b87eb7fcd938990ff2dbc9ca0a42d9c5d36fcaa75c7cf066f7995",
"lastState": {},
"name": "external-dns",
"ready": true,
"restartCount": 0,
"state": {
"running": {
"startedAt": "2019-02-28T16:22:57Z"
}
}
}
],
"hostIP": "172.20.39.147",
"phase": "Running",
"podIP": "100.96.7.3",
"qosClass": "Burstable",
"startTime": "2019-02-28T16:22:49Z"
}
},
I am just getting the name in here. Can someone please help me how to get Name, Node Name and Phase Values? find the below JSON as well.
Thanks, Much Appreciated
You were close with the code you posted. You just needed items[0] instead of items[1]. Remember the first element of an array is always 0. Other than that its as easy as checking the open and close brackets [] or {} to see where each nested object/array starts and ends.
Code:
var name = data.items[0].metadata.name
var nodeName = data.items[0].spec.nodeName
var phase = data.items[0].status.phase
snippet:
var data = {
"apiVersion": "v1",
"items": [{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"annotations": {
"kubernetes.io/limit-ranger": "LimitRanger plugin set: cpu request for container external-dns"
},
"creationTimestamp": "2019-02-28T16:22:49Z",
"generateName": "external-dns-5d69b66646-",
"labels": {
"app": "external-dns",
"pod-template-hash": "1825622202"
},
"name": "external-dns-5d69b66646-pmxmd",
"namespace": "default",
"ownerReferences": [{
"apiVersion": "extensions/v1beta1",
"blockOwnerDeletion": true,
"controller": true,
"kind": "ReplicaSet",
"name": "external-dns-5d69b66646",
"uid": "170d9260-3b75-11e9-abe2-0ec5819342ce"
}],
"resourceVersion": "2984",
"selfLink": "/api/v1/namespaces/default/pods/external-dns-5d69b66646-pmxmd",
"uid": "170e1a0d-3b75-11e9-abe2-0ec5819342ce"
},
"spec": {
"containers": [{
"args": [
"--source=service",
"--source=ingress",
"--provider=aws",
"--registry=txt",
"--txt-owner-id=qpair"
],
"image": "registry.opensource.zalan.do/teapot/external-dns:v0.4.2",
"imagePullPolicy": "IfNotPresent",
"name": "external-dns",
"resources": {
"requests": {
"cpu": "100m"
}
},
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"volumeMounts": [{
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"name": "default-token-rr546",
"readOnly": true
}]
}],
"dnsPolicy": "ClusterFirst",
"nodeName": "ip-172-20-39-147.ec2.internal",
"restartPolicy": "Always",
"schedulerName": "default-scheduler",
"securityContext": {},
"serviceAccount": "default",
"serviceAccountName": "default",
"terminationGracePeriodSeconds": 30,
"tolerations": [{
"effect": "NoExecute",
"key": "node.kubernetes.io/not-ready",
"operator": "Exists",
"tolerationSeconds": 300
},
{
"effect": "NoExecute",
"key": "node.kubernetes.io/unreachable",
"operator": "Exists",
"tolerationSeconds": 300
}
],
"volumes": [{
"name": "default-token-rr546",
"secret": {
"defaultMode": 420,
"secretName": "default-token-rr546"
}
}]
},
"status": {
"conditions": [{
"lastProbeTime": null,
"lastTransitionTime": "2019-02-28T16:22:49Z",
"status": "True",
"type": "Initialized"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2019-02-28T16:22:58Z",
"status": "True",
"type": "Ready"
},
{
"lastProbeTime": null,
"lastTransitionTime": "2019-02-28T16:22:49Z",
"status": "True",
"type": "PodScheduled"
}
],
"containerStatuses": [{
"containerID": "docker://18b96317cf360d562fb3f849c6716c50a41a67a4dbc126164020531e1e4d84a9",
"image": "registry.opensource.zalan.do/teapot/external-dns:v0.4.2",
"imageID": "docker-pullable://registry.opensource.zalan.do/teapot/external-dns#sha256:d54b9eb8948b87eb7fcd938990ff2dbc9ca0a42d9c5d36fcaa75c7cf066f7995",
"lastState": {},
"name": "external-dns",
"ready": true,
"restartCount": 0,
"state": {
"running": {
"startedAt": "2019-02-28T16:22:57Z"
}
}
}],
"hostIP": "172.20.39.147",
"phase": "Running",
"podIP": "100.96.7.3",
"qosClass": "Burstable",
"startTime": "2019-02-28T16:22:49Z"
}
}],
}
var name = data.items[0].metadata.name
var nodeName = data.items[0].spec.nodeName
var phase = data.items[0].status.phase
console.log(name)
console.log(nodeName)
console.log(phase)

Javascript: Loop through nested objects and arrays

I have an server response with data which has the structur as you can see in the codesnippet.
My goal is to iterate through each consent and add the channels
The data from the response:
[
{
"consents": [
{
"channels": [
{
"granted": true,
"id": "sms",
"title": "SMS/MMS"
},
{
"granted": true,
"id": "email",
"title": "E-Mail"
},
{
"granted": false,
"id": "phone",
"title": "Telefon"
},
{
"granted": false,
"id": "letter",
"title": "Brief"
}
],
"client": "App",
"configId": "99df8e86-2e24-4974-80da-74f901ba6a0d",
"date": "2018-03-08T16:03:25.753Z",
"granted": true,
"name": "bestandsdaten-alle-produkte",
"version": "1.0.0",
"versionId": "bd002dcd-fee6-42f8-aafe-22d0209a0646"
}
],
"createdAt": "2018-03-08T16:03:25.778Z",
"id": "1b9649a6-d8de-45c6-a0ae-a03cecf71cb5",
"updatedAt": "2018-03-08T16:03:25.778Z",
"username": "demo-app"
},
{
"consents": [
{
"channels": [
{
"granted": true,
"id": "sms",
"title": "SMS/MMS"
},
{
"granted": true,
"id": "email",
"title": "E-Mail"
},
{
"granted": true,
"id": "phone",
"title": "Telefon"
},
{
"granted": true,
"id": "letter",
"title": "Brief"
}
],
"client": "App",
"configId": "99df8e86-2e24-4974-80da-74f901ba6a0d",
"date": "2018-03-08T14:51:52.188Z",
"granted": true,
"name": "bestandsdaten-alle-produkte",
"version": "1.0.0",
"versionId": "bd002dcd-fee6-42f8-aafe-22d0209a0646"
}
],
"createdAt": "2018-03-08T14:51:52.208Z",
"id": "cf550425-990e-45ef-aaee-eced95d8fa08",
"updatedAt": "2018-03-08T14:51:52.208Z",
"username": "demo-app"
},
{
"consents": [
{
"channels": [
{
"granted": false,
"id": "sms",
"title": "SMS/MMS"
},
{
"granted": true,
"id": "email",
"title": "E-Mail"
},
{
"granted": true,
"id": "phone",
"title": "Telefon"
},
{
"granted": false,
"id": "letter",
"title": "Brief"
}
],
"client": "App",
"configId": "99df8e86-2e24-4974-80da-74f901ba6a0d",
"date": "2018-03-08T14:48:27.024Z",
"granted": true,
"name": "bestandsdaten-alle-produkte",
"version": "1.0.0",
"versionId": "bd002dcd-fee6-42f8-aafe-22d0209a0646"
}
],
"createdAt": "2018-03-08T14:48:27.054Z",
"id": "7fc1f087-2139-4494-bad7-161b0c6231a9",
"updatedAt": "2018-03-08T14:48:27.054Z",
"username": "demo-app"
},
]
The way i go is the following. But i need a way to append the channels to each Consent. Is there a way to solve this?
consentsList.forEach((consent, index, array) => {
consent.consents.forEach((c) => {
Object.keys(c).forEach((key) => {
dd.content.push(
{
columns: [
{
text: `${key}: `, style: 'text'
},
{
text: c[key], style: 'text'
}
]
}
);
});
});
Consents.push(consent);
if (index !== array.length - 1) {
dd.content.push({
margin: [0, 0, 0, 5],
canvas: [{
type: 'line', x1: 0, y1: 5, x2: 595 - (2 * 40), y2: 5, lineWidth: 0.6
}]
});
}
});
I want to output the individual channels where channels is on the top of each entry
You can extract the titles using map. And concantanate them using join like this.
let value = "";
if(key === "channels"){
value = c[key].map(x => x.title).join(" ,");
}
else {
value = c[key];
}
columns: [
{
text: `${key}: `, style: 'text'
},
{
text: value, style: 'text'
}
]
I have written a piece of code, hope this is what you're looking for. It is not optimized, try to optimize at your will
var a = responseData;
a.forEach(function(items) {
var allChannels = [];
items.consents.forEach(function(innerItems){
innerItems.channels.forEach(function(value){
allChannels.push(value.title);
})
items.allChannels = allChannels.join();
})
});
console.log(a);

Categories

Resources