1

I have a html-page with multiple json-elements and want to show content from one of them (jsonld of type book) into the page.

As long as there is only the needed json on the page, everything works fine. But i can't figure out how to adress the correct json once there is an additional json.

Do i need to make an additional loop with parsing the json an check for the type (but how to target the element then), or is there an easy and performant way (if-condition maybe?).

Any ideas, help and hints would be highly appreciated.

function codeAddress() {
var jsonld = JSON.parse(document.querySelector('script[type="application/ld+json"]').innerHTML);
document.getElementById('name').innerHTML = jsonld.name;
document.getElementById('buch-link').href =jsonld.sameAs;
document.getElementById('buch-link').title =jsonld.publisher.name + " - " + jsonld.author.name + " - " + jsonld.name;
document.getElementById('publisher').innerHTML = jsonld.publisher.name;	
document.getElementById('year').innerHTML = jsonld.copyrightYear;
document.getElementById('format').innerHTML = jsonld.bookFormat;
document.getElementById('pages').innerHTML = jsonld.numberOfPages;
document.getElementById('isbn').innerHTML = jsonld.isbn;
}
window.onload = codeAddress;
	
jQuery('#buchbeschreibung').parent('.panel-grid').prepend(jQuery('#leistungen:parent'));
<div class="book-data">
<p>
	<a id="buch-link" href="#" target="_blank" title="name"><strong id="name"></strong></a><br />
	<span id="publisher"></span>, <span id="year"></span><br />	
	<span id="format"></span>, <span id="pages"></span> Seiten<br />
	ISBN: <span id="isbn"></span><br />
</p>
</div>

<script type="application/ld+json">{
    "@context": "http://schema.org",
    "@type": "LocalBusiness",
    "image": "https://www.freie-lektoren.de/wp-content/uploads/Nehmen-Sie-Platz-e1546854168810.jpg",
    "priceRange": "$$",
    "telephone": "+49-30-306442-60",
    "additionalType": "http://www.productontology.org/doc/Lector",
    "name": "Freie Lektoren Obst &amp; Ohlerich",
    "logo": "https://www.freie-lektoren.de/wp-content/uploads/FreieLektoren_Logo.svg",
    "description": null,
    "openingHours": "Mo-Fr 9:00-15:30",
    "geo": {
        "@type": "GeoCircle",
        "geoMidpoint": {
            "@type": "GeoCoordinates",
            "latitude": null,
            "longitude": null
        },
        "geoRadius": "750"
    },
    "url": "https://www.freie-lektoren.de",
    "sameAs": [
        "https://www.facebook.com/freielektoren/"
    ],
    "contactPoint": {
        "@type": "ContactPoint",
        "telephone": "+49-30-306442-60",
        "contactType": "customer service",
        "email": "[email protected]",
        "contactOption": "",
        "areaServed": [
            "AT",
            "DE",
            "CH"
        ],
        "availableLanguage": [
            "English",
            "German"
        ]
    },
    "address": [
        {
            "@type": "PostalAddress",
            "addressCountry": "Germany",
            "addressLocality": "Gumtow",
            "addressRegion": "Brandenburg",
            "postalCode": "16866",
            "streetAddress": "Br\u00fcsenhagen 28"
        },
        {
            "@type": "PostalAddress",
            "addressCountry": null,
            "addressLocality": "Berlin",
            "addressRegion": "Berlin",
            "postalCode": "10179",
            "streetAddress": "Engeldamm 66"
        }
    ]
}</script>


<script type="application/ld+json">{
    "@context": "http://schema.org",
    "@type": "Book",
    "name": "Der Tote vom Elbhang",
    "author": {
        "@type": "Person",
        "name": "Anke K\u00fcpper"
    },
    "bookFormat": "Paperback",
    "isbn": "978-3959672993",
    "url": "https://www.freie-lektoren.de/?post_type=buecher&#038;p=10186",
    "sameAs": "https://www.harpercollins.de/products/der-tote-vom-elbhang-9783959678445",
    "publisher": {
        "@type": "Organization",
        "name": "HarperCollings"
    },
    "numberOfPages": "336",
    "copyrightYear": "2019",
    "genre": "Krimi",
    "inLanguage": "de-DE"
}</script>

2
  • 1
    It would be easier if you gave each JSON object a name, like var someObject = { ... }; because then you could access the properties without confusion like someObject.name. Commented Dec 7, 2019 at 12:20
  • You might consider using querySelectorAll instead of querySelector. This would return an array of found elements, not just single one. like: var jsonldArr = JSON.parse(document.querySelectorAll(... . Then when you have an array of book objects, you can find the required one: var jsonld = jsonldArr.find(<some condition>) Commented Dec 7, 2019 at 12:25

2 Answers 2

4

Loop through the JSON objects, and get the one you need:

function codeAddress() {
  // I used document.querySelectorAll() to grab all the ld+json items on the page
  const jsons = document.querySelectorAll('script[type="application/ld+json"]')
  const jsonld = []

  // transform the grabbed items' content to array of JSON objects
  jsons.forEach(e => jsonld.push(JSON.parse(e.innerHTML)))

  // return the created array
  return jsonld
}

// calling the DOM modification function with the array of
// parsed JSON objects, and querying it for @type === 'Book'
// so only return the JSON object that has a type of Book
window.onload = setBookInformation(codeAddress().find(e => e['@type'] === 'Book'));

// a separate function to handle DOM modifications
function setBookInformation(json) {
  document.getElementById('name').innerHTML = json.name;
  document.getElementById('buch-link').href = json.sameAs;
  document.getElementById('buch-link').title = json.publisher.name + " - " + json.author.name + " - " + json.name;
  document.getElementById('publisher').innerHTML = json.publisher.name;
  document.getElementById('year').innerHTML = json.copyrightYear;
  document.getElementById('format').innerHTML = json.bookFormat;
  document.getElementById('pages').innerHTML = json.numberOfPages;
  document.getElementById('isbn').innerHTML = json.isbn;
}

// jQuery('#buchbeschreibung').parent('.panel-grid').prepend(jQuery('#leistungen:parent'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="book-data">
  <p>
    <a id="buch-link" href="#" target="_blank" title="name"><strong id="name"></strong></a><br />
    <span id="publisher"></span>, <span id="year"></span><br />
    <span id="format"></span>, <span id="pages"></span> Seiten<br /> ISBN: <span id="isbn"></span><br />
  </p>
</div>

<script type="application/ld+json">
  {
    "@context": "http://schema.org",
    "@type": "LocalBusiness",
    "image": "https://www.freie-lektoren.de/wp-content/uploads/Nehmen-Sie-Platz-e1546854168810.jpg",
    "priceRange": "$$",
    "telephone": "+49-30-306442-60",
    "additionalType": "http://www.productontology.org/doc/Lector",
    "name": "Freie Lektoren Obst &amp; Ohlerich",
    "logo": "https://www.freie-lektoren.de/wp-content/uploads/FreieLektoren_Logo.svg",
    "description": null,
    "openingHours": "Mo-Fr 9:00-15:30",
    "geo": {
      "@type": "GeoCircle",
      "geoMidpoint": {
        "@type": "GeoCoordinates",
        "latitude": null,
        "longitude": null
      },
      "geoRadius": "750"
    },
    "url": "https://www.freie-lektoren.de",
    "sameAs": [
      "https://www.facebook.com/freielektoren/"
    ],
    "contactPoint": {
      "@type": "ContactPoint",
      "telephone": "+49-30-306442-60",
      "contactType": "customer service",
      "email": "[email protected]",
      "contactOption": "",
      "areaServed": [
        "AT",
        "DE",
        "CH"
      ],
      "availableLanguage": [
        "English",
        "German"
      ]
    },
    "address": [{
        "@type": "PostalAddress",
        "addressCountry": "Germany",
        "addressLocality": "Gumtow",
        "addressRegion": "Brandenburg",
        "postalCode": "16866",
        "streetAddress": "Br\u00fcsenhagen 28"
      },
      {
        "@type": "PostalAddress",
        "addressCountry": null,
        "addressLocality": "Berlin",
        "addressRegion": "Berlin",
        "postalCode": "10179",
        "streetAddress": "Engeldamm 66"
      }
    ]
  }
</script>


<script type="application/ld+json">
  {
    "@context": "http://schema.org",
    "@type": "Book",
    "name": "Der Tote vom Elbhang",
    "author": {
      "@type": "Person",
      "name": "Anke K\u00fcpper"
    },
    "bookFormat": "Paperback",
    "isbn": "978-3959672993",
    "url": "https://www.freie-lektoren.de/?post_type=buecher&#038;p=10186",
    "sameAs": "https://www.harpercollins.de/products/der-tote-vom-elbhang-9783959678445",
    "publisher": {
      "@type": "Organization",
      "name": "HarperCollings"
    },
    "numberOfPages": "336",
    "copyrightYear": "2019",
    "genre": "Krimi",
    "inLanguage": "de-DE"
  }
</script>

With the snippet above you can parse any number of JSON objects in your HTML, and work with them like a JavaScript object - query them, filter them, assign its values to DOM elements, etc.

Sign up to request clarification or add additional context in comments.

2 Comments

You are awesome! I didn't expect to an answer and the solution so quickly. This works like a charm. I just added a different onload as the json-ld was added after the window.onload (Wordpress Plugin adding Schema) document.addEventListener('readystatechange', event => { if (event.target.readyState === "complete") { setBookInformation(codeAddress().find(e => e['@type'] === 'Book')); } });
With WP you might be able to get the data right on the server (with some hooks the plugin might offer), and send a JSON down with wp_localize. That would be the best for the frontend, I think. But it may not worth the effort if the plugin that creates the ld+json is not really high quality (meaning it doesn’t have good hooks/APIs). But anyways, I’m happy that I could help :)
0

just give them a name!

<script>
var json1 = {
    "@context": "http://schema.org",
    "@type": "LocalBusiness",
    "image": "https://www.freie-lektoren.de/wp-content/uploads/Nehmen-Sie-Platz-e1546854168810.jpg",
    "priceRange": "$$",
    "telephone": "+49-30-306442-60",
    "additionalType": "http://www.productontology.org/doc/Lector",
    "name": "Freie Lektoren Obst &amp; Ohlerich",
    "logo": "https://www.freie-lektoren.de/wp-content/uploads/FreieLektoren_Logo.svg",
    "description": null,
    "openingHours": "Mo-Fr 9:00-15:30",
    "geo": {
      "@type": "GeoCircle",
      "geoMidpoint": {
        "@type": "GeoCoordinates",
        "latitude": null,
        "longitude": null
      },
      "geoRadius": "750"
    },
    "url": "https://www.freie-lektoren.de",
    "sameAs": [
      "https://www.facebook.com/freielektoren/"
    ],
    "contactPoint": {
      "@type": "ContactPoint",
      "telephone": "+49-30-306442-60",
      "contactType": "customer service",
      "email": "[email protected]",
      "contactOption": "",
      "areaServed": [
        "AT",
        "DE",
        "CH"
      ],
      "availableLanguage": [
        "English",
        "German"
      ]
    },
    "address": [{
        "@type": "PostalAddress",
        "addressCountry": "Germany",
        "addressLocality": "Gumtow",
        "addressRegion": "Brandenburg",
        "postalCode": "16866",
        "streetAddress": "Br\u00fcsenhagen 28"
      },
      {
        "@type": "PostalAddress",
        "addressCountry": null,
        "addressLocality": "Berlin",
        "addressRegion": "Berlin",
        "postalCode": "10179",
        "streetAddress": "Engeldamm 66"
      }
    ]
  };
  
  var json2 = { 
    "@context": "http://schema.org",
    "@type": "Book",
    "name": "Der Tote vom Elbhang",
    "author": {
        "@type": "Person",
        "name": "Anke K\u00fcpper"
    },
    "bookFormat": "Paperback",
    "isbn": "978-3959672993",
    "url": "https://www.freie-lektoren.de/?post_type=buecher&#038;p=10186",
    "sameAs": "https://www.harpercollins.de/products/der-tote-vom-elbhang-9783959678445",
    "publisher": {
        "@type": "Organization",
        "name": "HarperCollings"
    },
    "numberOfPages": "336",
    "copyrightYear": "2019",
    "genre": "Krimi",
    "inLanguage": "de-DE"}
</script>

then parse them by their names :

function codeAddress() {
var jsonld1 = JSON.parse(json1);
//your functions
}

1 Comment

This solution ist also correct. And of course easier / more cost effiecient as the It just doesn't work for me as the json is added by Wordpress-Plugins and i can't (easily) add names.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.