1

I am iterating over JSON-LD objects to create a list of user reviews, and this works here in JSFiddle (https://jsfiddle.net/vmgn1ykb/) but when I add it to my page using the either examples and test on Google Structured data testing tool I get an error "JSON-LD Syntax error: value, object or array expected." and the code doesn't run. Please help me understand why.

I have tried to change

 var arrayLength =  jsonld['review'].length;

to something like

 JSON.parse(document.querySelector('script[type="application/ld+json"]').innerText)

and

 JSON.parse(document.querySelector('script[id="jsonData"]').innerText)

But still the code wont run and the error in GSDTT persists. Please help understand what I am doing wrong.

This works,

var jsonld = {

"@context": "http://schema.org",
"@type": "Product",
"image": "https://www.myurl.com/media/db3e3b23f81585_M.jpg",
"name": "Test name",
"description": "Test review desc.",
"offers": {
    "@type": "AggregateOffer",
    "availability": "http://schema.org/InStock",
     "highPrice": "5195.00",
     "lowPrice": "2595.00",
      "offerCount": "1",
    "priceCurrency": "ZAR",
    "priceValidUntil": "2020-09-30",
    "url": "https://www.myurl.com/"
  }
,
"aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "5",
    "bestRating": "5",
    "reviewCount": "2"
  },
"review": [
    {
      "@type": "Review",
      "author": " Meagen",
      "description": "Test review desc",
      "reviewRating": {
        "@type": "Rating",
        "bestRating": "5",
        "ratingValue": "5",
        "worstRating": "1"
      }},
        {
      "@type": "Review",
      "author": " Ericka",
      "description": "Test review desc",
      "reviewRating": {
        "@type": "Rating",
        "bestRating": "5",
        "ratingValue": "5",
        "worstRating": "1"
      }}
      ]}

var arrayLength =  jsonld['review'].length;

outline = document.createElement('div');
outline.className = 'outline';
document.getElementsByTagName('body')[0].appendChild(outline);

for (i = 0; i < arrayLength; i++) {
    inside = document.createElement('div');
inside.className = 'inside';
document.getElementsByClassName('outline')[0].appendChild(inside);

//desc
desc = document.createElement('div');
desc.className = 'desc';
desc.innerHTML = JSON.stringify(jsonld.review[i].description);
document.getElementsByClassName('inside')[i].appendChild(desc);
//auth
auth = document.createElement('p');
auth.className = 'author';
auth.innerHTML = jsonld.review[i].author + " rated this tour " + jsonld.review[i].reviewRating.ratingValue + " out of 5";
document.getElementsByClassName('inside')[i].appendChild(auth);
//score
score = document.createElement('p');
score.className = 'score';
score.innerHTML = jsonld.review[i].reviewRating.ratingValue + " out of 5";
document.getElementsByClassName('inside')[i].appendChild(score);
}

But when I add it to my page using the script tags type="application/ld+json, this does not,

<script id="jsonData" type="application/ld+json">
var jsonld = {

"@context": "http://schema.org",
"@type": "Product",
"image": "https://www.myurl.com/media/db3e3b23f81585_M.jpg",
"name": "Test name",
"description": "Test review desc.",
"offers": {
    "@type": "AggregateOffer",
    "availability": "http://schema.org/InStock",
     "highPrice": "5195.00",
     "lowPrice": "2595.00",
      "offerCount": "1",
    "priceCurrency": "ZAR",
    "priceValidUntil": "2020-09-30",
    "url": "https://www.myurl.com/"
  }
,
"aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "5",
    "bestRating": "5",
    "reviewCount": "2"
  },
"review": [
    {
      "@type": "Review",
      "author": " Meagen",
      "description": "Test review desc",
      "reviewRating": {
        "@type": "Rating",
        "bestRating": "5",
        "ratingValue": "5",
        "worstRating": "1"
      }},
        {
      "@type": "Review",
      "author": " Ericka",
      "description": "Test review desc",
      "reviewRating": {
        "@type": "Rating",
        "bestRating": "5",
        "ratingValue": "5",
        "worstRating": "1"
      }}
      ]}
</script>        

<script type="text/javascript">
var arrayLength =  jsonld['review'].length;

outline = document.createElement('div');
outline.className = 'outline';
document.getElementsByTagName('body')[0].appendChild(outline);

for (i = 0; i < arrayLength; i++) {
    inside = document.createElement('div');
inside.className = 'inside';
document.getElementsByClassName('outline')[0].appendChild(inside);
//desc
desc = document.createElement('div');
desc.className = 'desc';
desc.innerHTML = JSON.stringify(jsonld.review[i].description);
document.getElementsByClassName('inside')[i].appendChild(desc);
//auth
auth = document.createElement('p');
auth.className = 'author';
auth.innerHTML = jsonld.review[i].author + " rated this tour " + jsonld.review[i].reviewRating.ratingValue + " out of 5";
document.getElementsByClassName('inside')[i].appendChild(auth);
//score
score = document.createElement('p');
score.className = 'score';
score.innerHTML = jsonld.review[i].reviewRating.ratingValue + " out of 5";
document.getElementsByClassName('inside')[i].appendChild(score);
}
</script>
2
  • The SDTT is very limited in what JavaScript it can run. Also, I don't think JavaScript is valid in a type application/ld+json. Doing json = is effectively turning it into a JavaScript command to add a string to a variable. It's not a json object. Commented Oct 9, 2019 at 21:18
  • 1
    Thanks @TonyMcCreath in my below update I removed the var declaration as indeed I don't think JS will validate inside JSON-LD, What I ended up doing was, var jsonld = JSON.parse(document.querySelector("#jsonData").innerText); inside my script to grab the selector and return and object. I assume the JSON remains in tact. Commented Oct 10, 2019 at 7:49

1 Answer 1

1

This is what I ended up doing and it works great now. There was also a problem the 'rev' was not referencing the correct container, duh.. changed to getElementsByClassName and fixed.

document.getElementsByClassName('rev')[0].appendChild(outline);

The full code..

            <script id="jsonData" type="application/ld+json">
            {
                "@context": "http://schema.org",
                "@type": "Product",

                "image": "https://www.myurl.com/media/k2/items/cache/3899dfe821813b23f81585_M.jpg",
                "name": "prod name",
                "description": "prod desc",
                "offers": {
                    "@type": "AggregateOffer",
                    "availability": "http://schema.org/InStock",
                    "highPrice": "5195.00",
                    "lowPrice": "2595.00",
                    "offerCount": "1",
                    "priceCurrency": "ZAR",
                    "priceValidUntil": "2020-09-30",
                    "url": "https://www.myurl.com/url"

                }
            ,
                    "aggregateRating": {
                    "@type": "AggregateRating",
                    "ratingValue": "5",
                    "bestRating": "5",
                    "reviewCount": "2"
                },

                "review": [
                    {
                    "@type": "Review",
                    "author": " Mea",
                    "description": "Test desc",
                    "reviewRating": {
                        "@type": "Rating",
                        "bestRating": "5",
                        "ratingValue": "5",
                        "worstRating": "1"
                    }},
                        {
                    "@type": "Review",
                    "author": " Eric",
                    "description": "Test desc",
                    "reviewRating": {
                        "@type": "Rating",
                        "bestRating": "5",
                        "ratingValue": "5",
                        "worstRating": "1"
                    }}
                    ]
            }

                </script>
                <div class="rev"> 
            </div>
                <script type="text/javascript">



            var jsonld = JSON.parse(document.querySelector("#jsonData").innerText);

            var arrayLength = JSON.parse(jsonld['aggregateRating'].reviewCount);

            outline = document.createElement('div');
                outline.className = 'outline';
                document.getElementsByClassName('rev')[0].appendChild(outline);

            for (i = 0; i < arrayLength; i++) {

                    inside = document.createElement('div');
                inside.className = 'inside';
                document.getElementsByClassName('outline')[0].appendChild(inside);

                //desc
                desc = document.createElement('div');
                desc.className = 'desc';
                desc.innerHTML = JSON.stringify(jsonld.review[i].description);
                document.getElementsByClassName('inside')[i].appendChild(desc);
            //auth
                auth = document.createElement('p');
                auth.className = 'author';
                auth.innerHTML = jsonld.review[i].author + " rated this tour " + jsonld.review[i].reviewRating.ratingValue + " out of 5";
                document.getElementsByClassName('inside')[i].appendChild(auth);
                //score
                score = document.createElement('p');
                score.className = 'score';
                score.innerHTML = jsonld.review[i].reviewRating.ratingValue + " out of 5";
                document.getElementsByClassName('inside')[i].appendChild(score);

            }
            </script>
Sign up to request clarification or add additional context in comments.

1 Comment

Here is a variation: $.getJSON("/file.jsonld",function(data){$("<script/>",{"type":"application/ld+json",html:JSON.stringify(data)}).appendTo("HTML-element");});

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.