Step through JSON until?

Hello, I require help with a JSON result that I am receiving. I want to get the results with jQuery, but anybody that can point me in the right direction would be good. What is going on is there is a node that is unique only with an extra member of current. It is in that current node where I need to retrieve the URI value listed there. How can this be done? Thanks

{
	"children" : 
	[
		{
			"children" : 
			[
				{
					"duration" : 402,
					"id" : "3",
					"name" : "Belly - Africa.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Belly%20-%20Africa.mp4"
				},
				{
					"duration" : 288,
					"id" : "4",
					"name" : "Beowulf - Sea Monsters.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Beowulf%20-%20Sea%20Monsters.mp4"
				},
				{
					"duration" : 564,
					"id" : "5",
					"name" : "Bugsy - Transcendent.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Bugsy%20-%20Transcendent.mp4"
				},
				{
					"duration" : 105,
					"id" : "6",
					"name" : "Cast Away - Faint.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Cast%20Away%20-%20Faint.mp4"
				},
				{
					"duration" : 316,
					"id" : "7",
					"name" : "Die Hard - Twinky.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Die%20Hard%20-%20Twinky.mp4"
				},
				{
					"current" : "current",
					"duration" : 293,
					"id" : "9",
					"name" : "Goodfellas - Growing Up.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Goodfellas%20-%20Growing%20Up.mp4"
				},
				{
					"duration" : 149,
					"id" : "10",
					"name" : "Gotti - 5, 10 Years.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Gotti%20-%205,%2010%20Years.mp4"
				},
				{
					"duration" : 360,
					"id" : "11",
					"name" : "Heat - Bank.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Heat%20-%20Bank.mp4"
				},
				{
					"duration" : 356,
					"id" : "13",
					"name" : "Kick-Ass - Im Hit Girl.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Kick-Ass%20-%20Im%20Hit%20Girl.mp4"
				},
				{
					"duration" : 230,
					"id" : "14",
					"name" : "Mambo Kings - Beautiful Maria.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Mambo%20Kings%20-%20Beautiful%20Maria.mp4"
				},
				{
					"duration" : 365,
					"id" : "15",
					"name" : "Misery - Don Pa-rig-non it is.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Misery%20-%20Don%20Pa-rig-non%20it%20is.mp4"
				},
				{
					"duration" : 435,
					"id" : "16",
					"name" : "Pink Panther SA - That felt good!.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Pink%20Panther%20SA%20-%20That%20felt%20good!.mp4"
				},
				{
					"duration" : 268,
					"id" : "17",
					"name" : "Rush Hour 2 - Ch,mon.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Rush%20Hour%202%20-%20Ch,mon.mp4"
				},
				{
					"duration" : 402,
					"id" : "18",
					"name" : "Silence of the Lambs - Think Marcus.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Silence%20of%20the%20Lambs%20-%20Think%20Marcus.mp4"
				},
				{
					"duration" : 445,
					"id" : "19",
					"name" : "Terminator 2 - Get Down.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/Terminator%202%20-%20Get%20Down.mp4"
				},
				{
					"duration" : 163,
					"id" : "20",
					"name" : "The Dark Knight - Sky Hook.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/The%20Dark%20Knight%20-%20Sky%20Hook.mp4"
				},
				{
					"duration" : 128,
					"id" : "21",
					"name" : "X2 - Night Crawler Save.mp4",
					"ro" : "rw",
					"type" : "leaf",
					"uri" : "file:///E:/mov/BSE/X2%20-%20Night%20Crawler%20Save.mp4"
				}
			],
			"id" : "1",
			"name" : "Playlist",
			"ro" : "ro",
			"type" : "node"
		},
		{
			"children" : [],
			"id" : "2",
			"name" : "Media Library",
			"ro" : "ro",
			"type" : "node"
		}
	],
	"id" : "0",
	"name" : "",
	"ro" : "rw",
	"type" : "node"
}

Thanks for any suggestions.

With the object in a variable called data, here is how you would do it with normal JavaScript:

const videos = data.children[0].children;
const current = videos.find(function (videoData) {
    return videoData.current === "current";
});
const currentUri = current.uri;

With jQuery I guess that you could use the inArray function instead, which would tell you if an array item exists with what you are looking for, but then you have to separately find the index and get the array item.

With normal JavaScript instead, the array method called find does all of that automatically for you.

I don’t see how for this task, jQuery could provide any improvement over normal JavaScript.

2 Likes

the code may flex juuust a little bit if the value isn’t guaranteed to be in children[0], but yes, vanilla JS is perfectly short and sweet for finding this node.

Good point. Let’s make the code flex.

First I’ll get rid of the intermediate videos variable:

const current = data.children[0].children.find(function (videoData) {
    return videoData.current === "current";
});
const currentUri = current.uri;
console.log({currentUri});

We can help to simplify things by extracting the function too:

function isCurrent(obj) {
    return obj.current === "current";
}
const current = data.children[0].children.find(isCurrent);
const currentUri = current.uri;
console.log({currentUri});

and that function might even be converted to arrow-notation instead:

const isCurrent = (obj) => obj.current === "current";

const current = data.children[0].children.find(isCurrent);
const currentUri = current.uri;
console.log({currentUri});

What happens when the first set of children have the videos somewhere other than index 0, such as at index 1?

const data = {
	"children" : 
	[
    	{}, // inserted to push children to index 1
		{
			"children" : 
			[

The code then needs to refer to index 1

const isCurrent = (obj) => obj.current === "current";

// const current = data.children[0].children.find(isCurrent);
const current = data.children[1].children.find(isCurrent);
const currentUri = current.uri;
console.log({currentUri});

Let’s now make that part more flexible too. We need to search through the array until we find the first situation where current is found. The problem though is that when we use the find method, we end up getting the whole array item.

So let’s work with that. We get the top-level child that has a list of videos, then we get the current value itself.

const isCurrent = (obj) => obj.current === "current";
const hasCurrent = (child) => child.children && child.children.find(isCurrent);

const videos = data.children.find(hasCurrent);
const currentUri = videos.children.find(isCurrent).uri;
console.log({currentUri});

Hah, funny that - the intermediate videos variable is required after all.

And if you’re confident about browsers supporting optional chaining, you can use ?. instead.

// const hasCurrent = (child) => child.children && child.children.find(isCurrent);
const hasCurrent = (child) => child.children?.find(isCurrent);

Do you think that provides enough flex?

1 Like