How do you create an application/ld+json
script
tag with a dynamically built JSON object in AngularJS .
This is what I need the script tag to look like
I have tried the following code but I cant get it to work:
HTML
{{jsonId|json}}
Controller
var myApp = angular.module('application', []); myApp.controller('TestController', ['$scope', function($scope) { $scope.jsonId = { "@context": "http://schema.org", "@type": "Place", "geo": { "@type": "GeoCoordinates", "latitude": "40.75", "longitude": "73.98" }, "name": "Empire State Building" }; }]);
The expression inside the script tag does not execute. The expression outside the script tag executes correctly and displays the JSON
Please see jsfiddle
After a cup of coffee I remembered there is a $sce
service with a trustAsHtml
function.
I created a directive that accepts a json
parameter for easy re-use
Please see updated and working code below:
HTML
Javascript
var myApp = angular.module('application', []); myApp.controller('TestController', ['$scope', function($scope) { $scope.jsonId = { "@context": "http://schema.org", "@type": "Place", "geo": { "@type": "GeoCoordinates", "latitude": "40.75", "longitude": "73.98" }, "name": "Empire State Building" }; }]).directive('jsonld', ['$filter', '$sce', function($filter, $sce) { return { restrict: 'E', template: function() { return ''; }, scope: { json: '=json' }, link: function(scope, element, attrs) { scope.onGetJson = function() { return $sce.trustAsHtml($filter('json')(scope.json)); } }, replace: true }; }]);
Here is a image of the script output
Please see updated jsfiddle

Tjaart van der Walt's answer did not work for me in the Google Test Tool. It did work with the real crawler. So I found another "old-school" solution which did the trick:
HTML
Angular
var schemaOrg = angular.toJson({ '@context': 'http://schema.org', '@type': 'MusicGroup', ... }); angular.element(document).ready(function() { var jsonLd = angular.element(document.getElementById('json-ld-music-group'))[0]; jsonLd.innerHTML = schemaOrg; });