Trying to access item in JSON from Bluesky

Given the following ultra-simplified JSON obtained via resources.GetRemote from the Bluesky API:

{
  "posts": [
    {
      "record": {
        "createdAt": "2024-02-24T21:39:11.227Z",
        "facets": [
          {
            "$type": "app.bsky.richtext.facet",
            "features": [
              {
                "$type": "app.bsky.richtext.facet#link",
                "uri": "https://steveklabnik.com/writing/how-does-bluesky-work"
              }
            ]
          }
        ]
      }
    }
  ]
}

…I am unable to get to the uri item within the features array. While Hugo does acknowledge the existence of (and allow me to reach):

  • posts
  • posts.record
  • posts.record.createdAt
  • posts.record.facets

…it draws the line at posts.record.facets.features, for which it says can't evaluate field features in type interface {} — so, obviously, I thus have no chance to get past that level to posts.record.facets.features.uri. Tried various proposed solutions I found on this forum and other sites, but no joy. Any help with this will be much appreciated.

P.S.: Even after this is resolved, how would I also get to posts.record.facets.features.$type, since the $ character creates its own problems? (This isn’t as important as the original question, above, but still perplexes me nonetheless.)

It’s easier to help you if you show your code. And even in JSON, there’s no ...facets.features.uri – only …facets.features[0].uri.

As to $type: you could probably use the index method.

1 Like

Well, for just one example from my efforts at debugging:

{{ with $json }}
	{{ range $json.posts }}
		{{ $posts := . }}
		{{ with $posts.record.facets }}
			{{ with $posts.record.facets.features }}
				{{ with $posts.record.facets.features.uri }}
					{{ . }}
				{{ else }}
					I got nothing
				{{ end }}
				<br>
			{{ end }}
		{{ end }}
	{{ end }}
{{ end }}

Incidentally, I did try the [0], also, but Hugo rejects the opening bracket as a bad character.

As I said: There is no record.facets.features.uri. The features property is referring to an array of objects (a slice in Hugo parlance). You must index into or iterate over that:

{{ range $posts.record.facets.features}}
  {{ with .uri}}
    {{.}}
  {{end}}
{{end}}

or something like that.

And I’d tried that variation, too, but {{ range $posts.record.facets.features}} (etc.) still gives back the can't evaluate field features in type interface {} error. I suspect, referring to your initial reply, there’s something about the missing [0] that is causing the problem, but don’t know how to get that through.

You’ve got several nested arrays. This will iterate over all posts, then over all the facets within “record”, then over all the features within each facet, finally display the .uri for each feature.

  {{ $data := "" }}
  {{ $url := "https://www.veriphor.com/shared/data/bw.json" }}
  {{ with resources.GetRemote $url }}
    {{ with .Err }}
      {{ errorf "%s" . }}
    {{ else }}
      {{ $data = .Content | transform.Unmarshal }}
    {{ end }}
  {{ else }}
    {{ errorf "Unable to get remote resource %q" $url }}
  {{ end }}

  {{ range $data.posts }}
    {{ range .record.facets }}
      {{ range .features }}
        {{ .uri }}
      {{ end }}
    {{ end }}
  {{ end }}
1 Like

Yep, that did it. Thank you, as always, sir.

1 Like

That [0] was referring to JavaScript (as we’re talking about the JavaScript Object Notation here). I wanted to illustrate what your structure would look like in JavaScript, after a JSON.parse(`{"posts": [...`)
As usual, @jmooring was on the spot with his explanation – I had only seen the last array, not the surrounding ones.

1 Like

Yes, it occurred to me during this exercise that, for once, I’d have found JS easier, but I wanted to Do Hugo :slight_smile: instead.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.