Manipulate Json in N8N

Describe the issue/error/question

I want to shorten this json to everything below subtasks

I have no idea how, since I am not into java

First try was

for (item of item) {
item.json.NewItem = item.json[“issues”];
}
works, but I do not know how to get better
PLUS
the data are only added below the original json

something like

var part_of_json = item.json[“issues”];
return part_of_json;

seems not to work

[
{
"expand": "names,schema",
"startAt": 2,
"maxResults": 1,
"total": 64,
"issues": [
{
"expand": "operations,versionedRepresentations,editmeta,changelog,renderedFields",
"id": "635145",
"self": "https://jiraabna.dfd-hamburg.de/rest/api/2/issue/635145",
"key": "DCSERV-7325",
"fields": {
"subtasks": [
{
"id": "635184",
"key": "DCSERV-7364",
"self": "https://jiraabna.dfd-hamburg.de/rest/api/2/issue/635184",
"fields": {
"summary": "Subtask 1",
"status": {
"self": "https://jiraabna.dfd-hamburg.de/rest/api/2/status/1",
"description": "The issue is open and ready for the assignee to start work on it.",
"iconUrl": "https://jiraabna.dfd-hamburg.de/images/icons/statuses/generic.png",
"name": "Open",
"id": "1",
"statusCategory": {
"self": "https://jiraabna.dfd-hamburg.de/rest/api/2/statuscategory/2",
"id": 2,
"key": "new",
"colorName": "blue-gray",
"name": "To Do"
}
},
"issuetype": {
"self": "https://jiraabna.dfd-hamburg.de/rest/api/2/issuetype/10000",
"id": "10000",
"description": "Die Unteraufgabe des Vorgangs",
"iconUrl": "https://jiraabna.dfd-hamburg.de/secure/viewavatar?size=xsmall&avatarId=13107&avatarType=issuetype",
"name": "Unteraufgabe",
"subtask": true,
"avatarId": 13107
}
}
},
{
"id": "635185",
"key": "DCSERV-7365",
"self": "https://jiraabna.dfd-hamburg.de/rest/api/2/issue/635185",
"fields": {
"summary": "Subtask 2",
"status": {
"self": "https://jiraabna.dfd-hamburg.de/rest/api/2/status/1",
"description": "The issue is open and ready for the assignee to start work on it.",
"iconUrl": "https://jiraabna.dfd-hamburg.de/images/icons/statuses/generic.png",
"name": "Open",
"id": "1",
"statusCategory": {
"self": "https://jiraabna.dfd-hamburg.de/rest/api/2/statuscategory/2",
"id": 2,
"key": "new",
"colorName": "blue-gray",
"name": "To Do"
}
},
"issuetype": {
"self": "https://jiraabna.dfd-hamburg.de/rest/api/2/issuetype/10000",
"id": "10000",
"description": "Die Unteraufgabe des Vorgangs",
"iconUrl": "https://jiraabna.dfd-hamburg.de/secure/viewavatar?size=xsmall&avatarId=13107&avatarType=issuetype",
"name": "Unteraufgabe",
"subtask": true,
"avatarId": 13107
}
}
}
]
}
}
],
}
] 
``

Hey @Laif, based on the example data you have provided I think you could use a Function node running code like this:

let subtasks = [];

for (item of items) {
  for (issue of item.json.issues) {
    console.log(issue);
    subtasks = subtasks.concat(issue.fields.subtasks);
  }
}

return subtasks.map(e => {
  return {
    json: e
  }
});

This runs through all incoming items and then for each item through again through each issue in the issues fields. Each subtask it finds would then be added to a subtasks array which is returned at the end.

Is this what you have in mind?

@MutedJam
Thanks for the quick response.
For a better understanding I would like to comment

let subtasks = ;

defines a new variable of type array

for (item of items) {

going through every (input) item → since here it should always be only one, so is it nessescary or could I start with items.json.issues directly?

for (issue of item.json.issues) {
console.log(issue);
subtasks = subtasks.concat(issue.fields.subtasks);
}
}

Going through the array in the json
Output on console
copy part of the array (issue.fields.subtasks) into variable subtasks

return subtasks.map(e => {
return {
json: e
}
});

Here I am not quite sure … everyelement of the array subtasks will be treated by the function e.
e changes the array into a json?

So is the output the one you had in mind? I wasn’t really sure about that when I wrote my answer :smiley:

As for your questions:

let subtasks = [];
defines a new variable of type array

Yes.

for (item of items) {
going through every (input) item → since here it should always be only one, so is it nessescary or could I start with items.json.issues directly?

If there’s only one item you could indeed use items[0].json instead and don’t need to run through all items. This is a 0-based index, so [0] references the first item of an array, [1] would be the second item and so on.

for (issue of item.json.issues) {
console.log(issue);
subtasks = subtasks.concat(issue.fields.subtasks);
}
}

Going through the array in the json
Output on console

Spot on (the console.log part is actually something I forgot to remove - it’s not needed for the transformation).

copy part of the array (issue.fields.subtasks) into variable subtasks

Yes, pretty much. It appends the items of the issue-specific issue.fields.subtasks array into our own subtasks array declared earlier.

return subtasks.map(e => {
return {
json: e
}
});

Here I am not quite sure … everyelement of the array subtasks will be treated by the function e.
e changes the array into a json?

So this returns the subtasks and transforms them on the fly using .map(), moving every item e in our subtasks array under a key json. This is because older versions of n8n expect a very specific data structure. More recent versions of n8n can also handle return subtasks; just fine:

image

So with your feedback in mind the code could be further simplified like so:

Hope this helps!