Using For Loop with JSON - json

I have a JSON object below and there are multiple nested divisions, the first without any identifiers. I am trying to get to the teams within the last divisions using a for loop, but I am not able to access them. Need some guidance.
{
"division": {
"division": [
{
"team": {
"id": "229525",
"name": "MyTeam",
"photo": "",
"visible": "True",
"RosterView": "True",
"PublicResults": "True",
"Statistics": "False",
"privilege": [
"False",
"True",
"True",
"True",
"True",
"True",
"True"
]
},
"name": "Boys 9-10",
"id": "12897",
"sort": "0",
"open": "0"
},
{
"team": [
{
"id": "229523",
"name": "Cougars",
"photo": "",
"visible": "True",
"RosterView": "True",
"PublicResults": "True",
"Statistics": "False",
"privilege": [
"False",
"True",
"True",
"True",
"True",
"True",
"True"
]
},

Update: Hmmm, after reading your JSON carefully, I notice that the 1st division has only 1 team since the team has only one object. But seems like the 2nd division has more than 1 team since there is an array of objects in team. I guess you have to handle the case where there only one team in a division.
Your for loop was almost right. Try this:
var divisions = JSONObject.division.division;
for (var i=0; i < divisions.length; i++) {
// handle division of one team here,
// don't need for loop if there only one team
// just do division[i].team.id
for (var j=0; j < divisions[i].length; j++) {
var teamId = divisions[i].team[j].id;
alert(teamId);
}
}
Your loop was
for (i=0; i <= JSONObject.division.division.teams[i].length; i++) { }
It has 2 problems, first you are skipping the last element by doing i <= ...length; i++
second, JSONObject.division.division.teams[i] is not an array, but this one JSONObject.division.division[i].team will give you an array of all the teams in a division. Then you can just get the team you want by its index in the array :)

First you should fix your parenthesis in json.
var a = {
"division": {
"division": [
{
"team": {
"id": "229525",
"name": "MyTeam",
"photo": "",
"visible": "True",
"RosterView": "True",
"PublicResults": "True",
"Statistics": "False",
"privilege": [
"False",
"True",
"True",
"True",
"True",
"True",
"True"
]
},
"name": "Boys 9-10",
"id": "12897",
"sort": "0",
"open": "0"
},
{
"team": [
{
"id": "229523",
"name": "Cougars",
"photo": "",
"visible": "True",
"RosterView": "True",
"PublicResults": "True",
"Statistics": "False",
"privilege": [
"False",
"True",
"True",
"True",
"True",
"True",
"True"
]
}
]
}
]
}
}
Then you can reach second 'team' object with:
a['division']['division'][1]['team'][0]['id'];
This will give you id. You can select anything you want. It is not so complicated. Just read it like a puzzle.
Here is live example: JSFiddle
here are some for loops :
var json1 = a['division']['division'][1]['team'][0]; // this is for second team array,
json2 = a['division']['division'][0]['team']; // this is for first team object,
for (obj in json1){
return json[obj];
};
According to your json, first and second teams are not in same data type. first team is array but second one is object. Thats why there are two different variables.

Related

Reformat JSON object using Dart

I need to standardize the object response key/values so that they are easier to parse/traverse using the tool I'm integrating.
Starting with the following JSON:
{
"status": true,
"body": {
"phone": "+1 937-830-1167",
"address": "2323 kuhku",
"linkedin": "uhku",
"twitter": "uhukh",
"education": "weeww",
"work_experience": "wewaew",
"write_something_about_you": "yugtyt",
"why_you_think_you_are_good_for_this_job": "kuhhuk",
"write_your_assignment_question": "kuhghuhghj",
"upload_your_attachment": null,
"upload_your_resume_here": null
}
}
Using Dart, what would be the best way to reformat as shown?
{
"status": true,
"body": {
"answers":[
{
"label": "phone",
"answer":"+1 937-830-1167"
},
{
"label": "address",
"answer":"2323 kuhku"
},
{
"label": "linkedin",
"answer": "uhku"
},
{
"label": "twitter",
"answer": "uhku"
},
{
"label": "education",
"answer": "uhku"
},
{
"label": "work_experience",
"answer": "uhku"
},
{
"label": "write_something_about_you",
"answer": "uhku"
},
{
"label": "why_you_think_you_are_good_for_this_job",
"answer": "uhku"
},
{
"label": "write_your_assignment_question",
"answer": "uhku"
},
{
"label": "upload_your_attachment",
"answer": "uhku"
},
{
"label": "write_something_about_you",
"answer": "upload_your_resume_here"
}
]
}
}
I'm somewhat limited by the tool I'm using so this will make it much easier to parse the JSON object with JSON Path as needed.
Looks like something that should be easily doable as:
var json = ... your json ...;
var result = {
"status": json["status"],
"body": [for (var e in json["body"].entries)
{"label": e.key, "answer": e.value}
]
};
Create a new JSON object with the same "status" and a "body" which is a list instead of a map, and for each entry in the original map, create a JSON object with a "label" and "answer" taken from the key and value of the map entry.

How to parameterize a part of string in a field of the response in karate

I am trying to print a response based on the particular parameters.
For that, I have the response from an API as below:
{
"ABC": {
"code": "ABC",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "0",
},
"priority": "1"
},
"DEF": {
"code": "DEF",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "1",
},
"priority": "1"
},
"GHI": {
"code": "GHI",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "2",
},
"priority": "1"
},
"JKL": {
"code": "JKL",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "0",
},
"priority": "1"
},
}
Here is the feature file that I am using to print that particular value:
Feature: Value extraction
Background:
* def all = [ABC,DEF,GHI,JKL]
Scenario: Extract response value
Given url
When method get
Then status 200
And def value = []
And eval for(var i=0;i<all.length;i++) {value.add(response['#(all[i])']["execution"]["status"]) }
And print value
I want to extract the value of all parameters whose status is "0".
print response["ABC"]["execution"]["status"]
The above line gives the result but I want to parameterise the ["ABC"] part
Any help on this? Is there any other way I can achieve this or am I doing something wrong to achieve this particular edge case?
I'm providing a sample below that answers multiple questions:
* def response =
"""
{
"ABC": {
"code": "ABC",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "0",
},
"priority": "1"
},
"DEF": {
"code": "DEF",
"isActive": "true",
"lastUpdatedBy": "username",
"execution": {
"status": "1",
},
"priority": "1"
}
}
"""
# get all values in root json
* def items = $.*
* def code = 'ABC'
* def found = items.filter(x => x.code == code && x.execution.status == '0')
* assert found.length == 1
# the expression on the right below is pure JS
* match found[0] == response[code]
Note:
how to use json-path to simplify JSON, also refer: https://stackoverflow.com/a/68811696/143475
how to use the filter() API to "find" data using complex expressions, that can be parameterized, also see: https://github.com/karatelabs/karate#json-transforms
how to get the value of a key that can be dynamic and parameterized

lodash sort an array of objects by a property which has an array of objects

I have a an object. I am able to sort the items by using lodash's _.orderBy().
However, in one of the scenario I have to sort by subject, which is an array of objects. Items inside the subject array are already sorted based on the name.
As subject is an array of the objects, I need to consider the first item for sorting.
[
{
"id": "1",
"name": "peter",
"subject": [
{
"id": "1",
"name": "maths"
},
{
"id": "2",
"name": "social"
}
]
},
{
"id": "2",
"name": "david",
"subject": [
{
"id": "2",
"name": "physics"
},
{
"id": "3",
"name": "science"
}
]
},
{
"id": "3",
"name": "Justin",
"subject": [
]
}
]
You can use _.get() to extract the name (or id) of the 1st item in subjects. If no item exists, _.get() will return undefined, which can be replaced with a default value. In this case, we don't want to use an empty string as a default value, since the order would change. Instead I'm checking if the value is a string, if it is I use lower case on it, if not I return it as is.
const arr = [{"id":"1","name":"peter","subject":[{"id":"1","name":"maths"},{"id":"2","name":"social"}]},{"id":"2","name":"david","subject":[{"id":"2","name":"physics"},{"id":"3","name":"science"}]},{"id":"3","name":"Justin","subject":[]}]
const result = _.orderBy(arr, o => {
const name = _.get(o, 'subject[0].name')
return _.isString(name) ? name.toLowerCase() : name
})
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Use _.sortBy with a comparison/sorting function argument. Your function itself can look into the receiving arguments subject key (I think its the subject you want to compare?)
Since you have the question also tagged with ES6 here is an JS only solution via Array.sort:
let arr = [ { "id": "1", "name": "peter", "subject": [ { "id": "1", "name": "maths" }, { "id": "2", "name": "social" } ] }, { "id": "2", "name": "david", "subject": [ { "id": "2", "name": "physics" }, { "id": "3", "name": "science" } ] }, { "id": "3", "name": "Justin", "subject": [] }, ]
const result = arr.sort((a,b) =>
a.subject.length && b.subject.length
? a.subject[0].name.localeCompare(b.subject[0].name)
: a.subject.length ? -1 : 1)
console.log(result)

Getting an API generated in-person signing envelope tracked through Salesforce Connect

I'm using the rest API to create an in person signing session from salesforce. My envelope creation json is like this:
{
"documents": [{
"documentBase64": "'+base64EncodedDocToSign+'",
"documentId": "1",
"fileExtension": "pdf",
"name": "contract.pdf"
}
],
"emailSubject": "Please Sign",
"recipients": {
"inPersonSigners": [{
"email": "some#gsome.com",
"name": "Luis",
"hostEmail": "some#gsome.com",
"hostName": "Luis",
"signerEmail": "other#gother.com",
"signerName": "Charles",
"recipientId": "1",
"tabs": {
"signHereTabs": [{
"anchorString": "s1",
"anchorXOffset": "0",
"anchorYOffset": "0",
"anchorIgnoreIfNotPresent": "false",
"anchorUnits": "inches"
}
]
},
"routingOrder": "1",
"clientUserId": "1000",
"embeddedRecipientStartURL": "SIGN_AT_DOCUSIGN",
}
]
},
"status": "sent"
}
The next step would be for the object to be tracked using Connect. Connect is properly configured for the object and works if I "Sign with Docusign" or use a custom button.
I understand I must change the json to include the DSFSSourceObjectId custom field, with value equal to the Id of the object that is originating the request, but if I try to get a customField in there the json is not properly formatted anymore.
I tried adding the customField like:
...
}
]
},
"customFields": [
{
"Name": "DSFSSourceObjectId",
"Value": "' + objectId + '"
}
],
"status": "sent"
}
Is this viable?
I got this working adding the following to the JSON:
"customFields": {
"textCustomFields": [{
"value": "salesforceId",
"required": "false",
"show": "false",
"name": "DSFSSourceObjectId"
}
]
},

Extract values in json object with awk/sed, but cannot get it to work

I have a file with the return of a curl statement in it, in the form of json. Each object has a set of values, but the parameters for these values are all called the same names. See code below.
These objects are part of a larger object called workflow. The Cleaning up object is the last process that runs in our workflow. For every video that passes through the workflow, a json file in this format is created. (There are more than only these three objects, this is just for illustrative purposes)
I want to take the value of completed of the object with "description": "Cleaning up" and store it as a variable $end_time. Then I want to take the value of completed of the object with "description": "Ingest" and store it as a variable $start_time. These two values are then subtracted to give me an integer time in milliseconds so I can calculate the time it took for the video to go through this part of the process. With the maths part I am fine, and know how to do it. It is the extraction of the values that I am struggling with.
I hope this makes sense? ANY help would be appreciated. Thank you in advance!
EDIT: Had to delete original code in post, due to character limitations
Here is a proper example of the file that I have to work with:
{
"workflows": {
"count": "20",
"searchTime": "1",
"startPage": "0",
"totalCount": "1",
"workflow": {
"configurations": {
"configuration": [
{
"$": "1409750880000",
"key": "schedule.start"
},
{
"$": "1409755980000",
"key": "schedule.stop"
},
{
"$": "Capture_agent",
"key": "schedule.location"
},
{
"$": "false",
"key": "trimHold"
},
{
"$": "true",
"key": "archiveOp"
},
{
"$": "false",
"key": "captionHold"
},
{
"$": "false",
"key": "videoPreview"
}
]
},
"creator": {
"organization": "mh_default_org",
"roles": [
"76b1bdde-a080-40a4-b929-bde89af6a0a8_Instructor",
"ROLE_ADMIN",
"ROLE_ANONYMOUS",
"ROLE_USER"
],
"userName": user_name
},
"description": "This workflow definition defines the steps involved in scheduling a recording, capturing it, and\n ingesting it, after which processing operations may be added.\n ",
"errors": "",
"id": "15518",
"mediapackage": {
"attachments": "",
"creators": {
"creator": "Name"
},
"id": "2d25ed19-2978-458d-a4a0-c9c56d791c68",
"license": "Creative Commons 3.0: Attribution-NonCommercial-NoDerivs",
"media": "",
"metadata": "",
"publications": {
"publication": {
"channel": "engage-player",
"id": "b7b68f91-2c33-4673-ba7c-2e9b891788f9",
"mimetype": "text/html",
"tags": "",
"url": "http://some.url.com:80/engage/ui/watch.html?id=2d25ed19-2978-458d-a4a0-c9c56d791c68"
}
},
"series": "76b1bdde-a080-40a4-b929-bde89af6a0a8",
"seriestitle": "Recording_Title_user_name",
"start": "2014-09-03T13:28:00Z",
"title": "Recording_Title"
},
"operations": {
"operation": [
{
"abortable": "false",
"completed": 1409750882092,
"configurations": {
"configuration": [
{
"$": "1409750880000",
"key": "schedule.start"
},
{
"$": "1409755980000",
"key": "schedule.stop"
},
{
"$": "Capture_agent",
"key": "schedule.location"
}
]
},
"continuable": "false",
"description": "Scheduled",
"execution-history": "",
"execution-host": "http://some.url.com:8080",
"fail-on-error": "true",
"failed-attempts": "0",
"hold-action-title": "View schedule",
"holdurl": "/workflow/hold/org.opencastproject.workflow.handler.scheduleworkflowoperationhandler",
"id": "schedule",
"job": "15519",
"max-attempts": "1",
"retry-strategy": "none",
"started": 1409750881745,
"state": "SUCCEEDED",
"time-in-queue": 0
},
{
"abortable": "false",
"configurations": "",
"continuable": "false",
"description": "Capture",
"execution-history": "",
"execution-host": "http://some.url.com:8080",
"fail-on-error": "true",
"failed-attempts": "0",
"hold-action-title": "Monitor capture",
"holdurl": "/workflow/hold/org.opencastproject.workflow.handler.captureworkflowoperationhandler",
"id": "capture",
"job": "42894",
"max-attempts": "1",
"retry-strategy": "none",
"started": 1409750884085,
"state": "SKIPPED",
"time-in-queue": 0
},
{
"completed": 1409756171224,
"configurations": "",
"description": "Ingest",
"execution-history": "",
"fail-on-error": "true",
"failed-attempts": "0",
"id": "ingest",
"max-attempts": "1",
"retry-strategy": "none",
"state": "SUCCEEDED"
},
{
"completed": 1409854379552,
"configurations": {
"configuration": {
"key": "preserve-flavors"
}
},
"description": "Cleaning up",
"execution-history": "",
"execution-host": "http://some.url.com:8080",
"fail-on-error": "false",
"failed-attempts": "0",
"id": "cleanup",
"job": "45113",
"max-attempts": "1",
"retry-strategy": "none",
"started": 1409854378128,
"state": "SUCCEEDED",
"time-in-queue": 0
}
]
},
"organization": {
"adminRole": "ROLE_ADMIN",
"anonymousRole": "ROLE_ANONYMOUS",
"id": "mh_default_org",
"name": "Opencast Project",
"properties": {
"property": [
{
"$": "true",
"key": "adminui.i18n_tab_episode.enable"
},
{
"$": "false",
"key": "adminui.i18n_tab_users.enable"
},
{
"$": "/engage/ui/img/mh_logos/OpencastLogo.png",
"key": "logo_small"
},
{
"$": "http://opencast.org/matterhorn/",
"key": "engageui.link_mobile_redirect.url"
},
{
"$": "false",
"key": "engageui.annotations.enable"
},
{
"$": "true",
"key": "engageui.links_media_module.enable"
},
{
"$": "2024",
"key": "adminui.chunksize"
},
{
"$": "false",
"key": "adminui.series_prepopulate.enable"
},
{
"$": "true",
"key": "engageui.link_download.enable"
},
{
"$": "false",
"key": "engageui.link_mobile_redirect.enable"
},
{
"$": "For more information have a look at the official site.",
"key": "engageui.link_mobile_redirect.description"
},
{
"$": "/engage/ui/img/mh_logos/MatterhornLogo_large.png",
"key": "logo_large"
}
]
},
"servers": {
"server": {
"name": "localhost",
"port": "8080"
}
}
},
"parent": {
"nil": "true"
},
"state": "SUCCEEDED",
"template": "full",
"title": "Scheduled Workflow"
}
}
}
Here is a jq example that should point you to getting what you want:
#!/bin/bash
# Assuming the json is in a file workflow.json
end_time=$( jq '.workflows.workflow.operations.operation[] | select(.description == "Cleaning up") | .completed' < workflow.json )
start_time=$( jq '.workflows.workflow.operations.operation[] | select(.description == "Ingest") | .completed' < workflow.json )
This is assuming the input you have is in an JSON array called workflow at the top level. Here's this on the command line:
$ jq '.workflows.workflow.operations.operation[] | select(.description == "Ingest") | .completed' < workflow.json
1406051539118
$ jq '.workflows.workflow.operations.operation[] | select(.description == "Cleaning up") | .completed' < workflow.json
1406051695440