I have this json data which I need to convert into an object. The json has a parent/child relationship instead of actual children object in the parent object.
{ "queryType": "tree", "queryResultType": "workItemLink", "workItemRelations": [ { "rel": null, "source": null, "target": { "id": 1166167, "url": "https://dev.azure.com/org/_apis/wit/workItems/1166167" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "source": { "id": 1166167, "url": "https://dev.azure.com/org/_apis/wit/workItems/1166167" }, "target": { "id": 1167481, "url": "https://dev.azure.com/org/_apis/wit/workItems/1167481" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "source": { "id": 1167481, "url": "https://dev.azure.com/org/_apis/wit/workItems/1167481" }, "target": { "id": 1234896, "url": "https://dev.azure.com/org/_apis/wit/workItems/1234896" } } ] } What I've done so far. Please note that the code below is not the actual code but are snippets I took from the actual code for simplicity.
import axios from 'axios'; interface Item { id: number; children: Item[]; } interface WiqlResponse { queryType: string; queryResultType: string; asOf: string; workItemRelations: Array<{ rel: string; source: { id: number; url: string } | null; target: { id: number; url: string }; }> } export async function getWiql(wiql: string): Promise<WiqlResponse> { const response = await axios.get<WiqlResponse>(`/org/_apis/wit/wiql/${wiql}?api-version=7.1`); return response.data; } export async function main() { getWiql('123123213').then(wiqlResponse => { // Get all parent work items for (const pRel of wiqlResponse.workItemRelations.filter(r => r.rel == null)) { let childs: Item[] = []; // Get all children of this parent for (const cRel of wiqlResponse.workItemRelations.filter(r => r.source?.id == pRel.target.id)) { let child: Item = { id: cRel.target.id, children: [] }; childs.push(child); } let parent: Item = { id: pRel.target.id, children: childs }; } }); } The code above will work up to level 2 only but if you look closely at the json data, it has 3 level and could be more depending on the data from the source.
How can I recursively check if there are still child items?
EDIT: Here's a sample code that can be run without axios.
interface Item { id: number; children: Item[]; } interface WiqlResponse { workItemRelations: Array<{ rel: string | null; source: { id: number; url: string } | null; target: { id: number; url: string }; }> } const wiqlResponse: WiqlResponse = { "workItemRelations": [ { "rel": null, "source": null, "target": { "id": 1166167, "url": "https://dev.azure.com/org/_apis/wit/workItems/1166167" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "source": { "id": 1166167, "url": "https://dev.azure.com/org/_apis/wit/workItems/1166167" }, "target": { "id": 1167481, "url": "https://dev.azure.com/org/_apis/wit/workItems/1167481" } }, { "rel": "System.LinkTypes.Hierarchy-Forward", "source": { "id": 1167481, "url": "https://dev.azure.com/org/_apis/wit/workItems/1167481" }, "target": { "id": 1234896, "url": "https://dev.azure.com/org/_apis/wit/workItems/1234896" } } ] }; export async function main() { console.log('wiqlResponse: ', wiqlResponse); let items: Item[] = []; // Get all parent work items for (const pRel of wiqlResponse.workItemRelations.filter(r => r.rel == null)) { let childs: Item[] = []; // Get all children of this parent for (const cRel of wiqlResponse.workItemRelations.filter(r => r.source?.id == pRel.target.id)) { let child: Item = { id: cRel.target.id, children: [] }; childs.push(child); } let parent: Item = { id: pRel.target.id, children: childs }; items.push(parent); } console.log('items:', JSON.stringify(items)); } main(); EDIT: Apologies for not explaining the relationship of the json data.
The json provides a relationship between source and target. The target is a top most parent if it doesn't have a source. If the relationship has both source and target, the target is the child of the source.
EDIT: Adding the expected result for clarity. Again my apologies for not being concise the first time.
The expected result should be:
[ { "id": 1166167, "children": [ { "id": 1167481, "children": [ { "id": 1234896, "children": [] } ] } ] } ]