How to parse JSON-LD returned by "Knowledge Graph Search API" in vue3

34 views Asked by At

It seems I'm too dumb or just blind, because I can't get that right.
My other Google API (Books API) works like a charm.
It's easy going with JSON-styled return data.

But this "Knowledge Graph Search API" of Google returns JSON-LD-styled data.

Doing this in a browser as URL works as expected:

https://kgsearch.googleapis.com/v1/entities:search?query=LoremIpsum&key=VUE_APP_GOOGLE_API_KEY&ident=True

Something like this:

{
  "@context": {
    "goog": "http://schema.googleapis.com/",
    "resultScore": "goog:resultScore",
    "EntitySearchResult": "goog:EntitySearchResult",
    "detailedDescription": "goog:detailedDescription",
    "kg": "http://g.co/kg",
    "@vocab": "http://schema.org/"
  },
  "@type": "ItemList",
  "itemListElement": [
    {
      "result": {
        "@id": "kg:/g/11f266hnh5",
        "name": "Blupp",
        "@type": [
          "Thing"
        ],
        "description": "Song by Jan Garbarek Quartet"
      },
      "@type": "EntitySearchResult",
      "resultScore": 46.472198486328118
    },
    {
      "@type": "EntitySearchResult",
      "result": {
        "name": "Bluppo",
        "@type": [
          "VideoGame",
          "CreativeWork",
          "SoftwareApplication",
          "Thing"
        ],
        "@id": "kg:/m/097m49",
        "description": "Arcade game"
      },
      "resultScore": 19.4659481048584
    },

Now in vue3:

  1. My input field:

    <td class="inputField">
       <input @keyup.enter="search" v-model="this.inputTitle" id="global-input" type="text" placeholder="Freitext"/>
       </td>
    
  2. My search function

    <script>
    import { globalSearch } from "../api/films-api.js";
    ....
    methods: {
            async search() {
              await globalSearch(this.inputTitle).then((response) => {
                if (response.items) {
                  this.films = response.item;
                } else {
                  this.films = {};
                }
              });
            },
    
  3. My globalSearch function

    export async function globalSearch(query) {
    return new Promise((resolve, reject) => {
        console.log("url: " + BASE_URL +
            query +
            "&" +
            key + process.env.VUE_APP_GOOGLE_API_KEY + "&" +
            indent + "True");
    
        fetch(BASE_URL +
                query +
                "&" +
                key + process.env.VUE_APP_GOOGLE_API_KEY + "&"+
                indent + "True"
                )
            .then((response) => {
                resolve(response); // <- a promise Object I can't work with
            })
            .catch((err) => {
                console.log("err: " + err.message);
                reject(err.message);
            });
    });
    }
    

What can I do with this response?

  1. When I put it in a console.log(response);

[object Response] 2. When I do json.parse(response)
err: JSON.parse: unexpected character at line 1 column 2 of the JSON data 3. resolve(response)
> gives me: undefined

All I need is just the tag '"itemListElement":' and below to read out the 'result' blocks.
Can that be so difficult?
I even played with "jsonld" package (npm install jsonld).
That gives you some obscure methods like flatten and stuff.
Do I really need this? sigh
Please help.

1

There are 1 answers

0
Eager2Learn On BEST ANSWER

Thanks for investigating...
Now it works, I don't know why, but it works. :-)

resolve(response.json()); is still undefined, when printed to console via console.log() in my function below.

export async function globalSearch(query) {
    return new Promise((resolve, reject) => {
        console.log("url: " + BASE_URL + query + "&" + key + process.env.VUE_APP_GOOGLE_API_KEY + "&"+ indent + "True");
        fetch(BASE_URL +
                query +
                "&" +
                key + process.env.VUE_APP_GOOGLE_API_KEY + "&"+
                indent + "True"
                )
                .then((response) => {
                    resolve(response.json());
                })
                .catch((err) => {
                    reject(err.message);
                });
    });
}

But response.itemListElements holds exactly the data I need.

async search() {
   await globalSearch(this.inputTitle).then((response) => {
      console.log("response.itemListElement: " + response.itemListElement);
       if (response.itemListElement) {
           this.films = response.itemListElement;
       } else {
           this.films = {};
        }
    })
},