0

I am using the following code, to grab data from YouTube API JSON Feed. I am able to get the data that I want, however. It is repeating the same data for the number of rows in the list.

    Dim n As New WebClient()
    Dim jsonString As String = n.DownloadString("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet%2C+id&playlistId=PLCJLiJ8uSJrCpxwz4lmnz1NvvF2SzXbhk&key=YOUR_API_KEY")

    Dim jo = Newtonsoft.Json.Linq.JObject.Parse(jsonString)
    For Each Row In jo
        Dim VidID = jo("items")(0)("snippet")("resourceId")("videoId")
        Response.Write(VidID)
    Next

A sample of JSON (Sorry it was not added earlier. Thought I did, totally missed the ball on this one.)

{
"kind":    "youtube#playlistItemListResponse",
"etag":    "\"m2yskBQFythfE4irbTIeOgYYfBU/YJYLWeQ7ZaYKr3ce1Z9EIjD9WVU\"",
"nextPageToken":    "CAUQAA",
"pageInfo":    {
 "totalResults":    10,
 "resultsPerPage":    5
},
"items":    [
 {
     "kind":    "youtube#playlistItem",
     "etag":    "\"m2yskBQFythfE4irbTIeOgYYfBU/0TyxpFnbR5GigaSoRo2gAPfUHwE\"",
     "id":    "UExDSkxpSjh1U0pyQ3B4d3o0bG1uejFOdnZGMlN6WGJoay41NkI0NEY2RDEwNTU3Q0M2",
     "snippet":    {
      "publishedAt":    "2014-12-10T21:16:39.000Z",
      "channelId":    "UCVUx0VcNxnHx7ZjuZK5Sthw",
      "title":    "Private    video",
      "description":    "This    video    is    private.",
      "channelTitle":    "Late    Show    with    David    Letterman",
      "playlistId":    "PLCJLiJ8uSJrCpxwz4lmnz1NvvF2SzXbhk",
      "position":    0,
      "resourceId":    {
          "kind":    "youtube#video",
          "videoId":    "4bVgilYncao"
      }
     }
 },
 {
     "kind":    "youtube#playlistItem",
     "etag":    "\"m2yskBQFythfE4irbTIeOgYYfBU/PVF3VoVEG0X1jmV6GeUNhpCIzF4\"",
     "id":    "UExDSkxpSjh1U0pyQ3B4d3o0bG1uejFOdnZGMlN6WGJoay4yODlGNEE0NkRGMEEzMEQy",
     "snippet":    {
      "publishedAt":    "2014-12-10T21:16:58.000Z",
      "channelId":    "UCVUx0VcNxnHx7ZjuZK5Sthw",
      "title":    "Private    video",
      "description":    "This    video    is    private.",
      "channelTitle":    "Late    Show    with    David    Letterman",
      "playlistId":    "PLCJLiJ8uSJrCpxwz4lmnz1NvvF2SzXbhk",
      "position":    1,
      "resourceId":    {
          "kind":    "youtube#video",
          "videoId":    "H9eYkpgeeI8"
      }
     }
 },
 {
     "kind":    "youtube#playlistItem",
     "etag":    "\"m2yskBQFythfE4irbTIeOgYYfBU/BLUJWU0eHjBeEizXySdnzUhi2lQ\"",
     "id":    "UExDSkxpSjh1U0pyQ3B4d3o0bG1uejFOdnZGMlN6WGJoay4wMTcyMDhGQUE4NTIzM0Y5",
     "snippet":    {
      "publishedAt":    "2014-12-10T21:17:14.000Z",
      "channelId":    "UCVUx0VcNxnHx7ZjuZK5Sthw",
      "title":    "Private    video",
      "description":    "This    video    is    private.",
      "channelTitle":    "Late    Show    with    David    Letterman",
      "playlistId":    "PLCJLiJ8uSJrCpxwz4lmnz1NvvF2SzXbhk",
      "position":    2,
      "resourceId":    {
          "kind":    "youtube#video",
          "videoId":    "ONgN2Hgz3XE"
      }
     }
 },
 {
     "kind":    "youtube#playlistItem",
     "etag":    "\"m2yskBQFythfE4irbTIeOgYYfBU/qlX2iXH1WPg7D3-eq7jInjQyj2c\"",
     "id":    "UExDSkxpSjh1U0pyQ3B4d3o0bG1uejFOdnZGMlN6WGJoay41MjE1MkI0OTQ2QzJGNzNG",
     "snippet":    {
      "publishedAt":    "2014-12-10T21:17:30.000Z",
      "channelId":    "UCVUx0VcNxnHx7ZjuZK5Sthw",
      "title":    "Private    video",
      "description":    "This    video    is    private.",
      "channelTitle":    "Late    Show    with    David    Letterman",
      "playlistId":    "PLCJLiJ8uSJrCpxwz4lmnz1NvvF2SzXbhk",
      "position":    3,
      "resourceId":    {
          "kind":    "youtube#video",
          "videoId":    "1Ee4bfu_t3c"
      }
     }
 },
 {
     "kind":    "youtube#playlistItem",
     "etag":    "\"m2yskBQFythfE4irbTIeOgYYfBU/698H3tj04Cx7lZ8z4rHjL4DPtUI\"",
     "id":    "UExDSkxpSjh1U0pyQ3B4d3o0bG1uejFOdnZGMlN6WGJoay4wOTA3OTZBNzVEMTUzOTMy",
     "snippet":    {
      "publishedAt":    "2014-12-10T21:17:47.000Z",
      "channelId":    "UCVUx0VcNxnHx7ZjuZK5Sthw",
      "title":    "Private    video",
      "description":    "This    video    is    private.",
      "channelTitle":    "Late    Show    with    David    Letterman",
      "playlistId":    "PLCJLiJ8uSJrCpxwz4lmnz1NvvF2SzXbhk",
      "position":    4,
      "resourceId":    {
          "kind":    "youtube#video",
          "videoId":    "Bzr5VtFvSyw"
    }
   }
  }
 ]
}

Any information on returning the correct data in this loop, instead of duplicates? The data that I need, is the videoId from every listing.

Thanks, everyone.

CodingEE

CodingEE
  • 129
  • 2
  • 14
  • 1
    If you want all values better to deserialize - no looping required. – Ňɏssa Pøngjǣrdenlarp Apr 11 '17 at 23:48
  • Hey, Plutonix. Would you perhaps have a sample code or link, possibly? I found this one. http://www.newtonsoft.com/json/help/html/DeserializeObject.htm However, I am not certain if this is what I need or not? – CodingEE Apr 12 '17 at 00:04
  • 2
    Without a json string example, it's hard to see your problem, but maybe since you are looping through "JO" you should reference each ROW (not JO). – RonB Apr 12 '17 at 09:53
  • It might be easier for you to use [`SelectTokens`](http://www.newtonsoft.com/json/help/html/QueryJsonSelectTokenJsonPath.htm) with a wildcard as shown [here](https://stackoverflow.com/a/42820388/3744182) or [here](https://stackoverflow.com/a/39337136/3744182). But to properly answer your question we would need a [mcve] that includes sample JSON. – dbc Apr 12 '17 at 18:43
  • To be honest. I THOUGH that I had provided it. I had it ready, but did not post it. Sorry about that. Will post an example now. – CodingEE Apr 12 '17 at 19:40

1 Answers1

0

The Newtonsoft documentation pages Querying JSON with LINQ and Querying JSON with SelectToken describe how you can query for values nested inside a JObject hierarchy once loaded.

For instance, using SelectTokens(), you can query for the "videoId" values as follows:

' Get all videoId values, convert to strings, and store in an array:
Dim VidIDs = jo.SelectTokens("items[*].snippet.resourceId.videoId") _
        .Select(Function(c) c.ToString()) _
        .ToList()

Here I am using the wildcard operator [*] to match all elements in the "items" array. This is a standard operator of JSONPath query syntax which SelectTokens() supports.

Here is the equivalent logic using LINQ:

Dim query = From item In jo("items")
    Let videoId = item("snippet")("resourceId")("videoId").ToString()
    Select videoId
Dim VidIDs = query.ToList()

(Note that the SelectTokens code automatically skips over items missing a video ID while the LINQ code will throw a null reference exception.)

The reason your code does not work is that, while JObject implements many different IEnumerable<T> intrerfaces, the one it implements directly is public IEnumerator<KeyValuePair<string, JToken>> GetEnumerator(). Thus your Row has type KeyValuePair<string, JToken> and so Row("items") does not compile.

Sample fiddle.

dbc
  • 104,963
  • 20
  • 228
  • 340