Reputation: 67
I have been tinkering with AngularJS directives and I do not understand why my attempt to build an iframe src attribute with an expression is triggering an error. The thrown error references the following URL, but I'm afraid I don't find it very enlightening:
http://errors.angularjs.org/1.3.14/$interpolate/noconcat?p0=https%3A%2F%2Fwww.youtube.com%2Fembed%2F%7B%7BvideoId%7D%7D
What does that really mean and what can I do about it?
Here are the relevant JavaScript and HTML:
angular.module("myModule", [])
.directive("myDirective", function() {
return {
restrict: "EA",
scope: {
videoId: "@videoId",
width: "@width",
height: "@height"
},
// This seems to work as expected.
//template: '<iframe width="432" height="243" src="https://www.youtube.com/embed/8aGhZQkoFbQ" frameborder="0" allowfullscreen></iframe>',
// This seems to work as expected except for adding a little extra whitespace after the values.
//template: '<iframe width="{{width}}" height="{{height}}" src="https://www.youtube.com/embed/8aGhZQkoFbQ" frameborder="0" allowfullscreen></iframe>',
// This throws an error that refers to http://errors.angularjs.org/1.3.14/$interpolate/noconcat?p0=https%3A%2F%2Fwww.youtube.com%2Fembed%2F%7B%7BvideoId%7D%7D.
template: '<iframe width="432" height="243" src="https://www.youtube.com/embed/{{videoId}}" frameborder="0" allowfullscreen></iframe>',
replace: true
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<my-directive video-id="8aGhZQkoFbQ" width="432" height="243"></my-directive>
My thanks for any enlightenment.
I am leaving the above in place for reference, but here is an edited version using a controller and $sce.trustAsResourceUrl as suggested in Muhammad Reda's answer in case it can help anyone to see it all together:
angular.module("myModule", ["ngSanitize"])
.directive("myDirective", function() {
return {
restrict: "EA",
scope: {
videoId: "@videoId",
width: "@width",
height: "@height"
},
template: '<iframe width="432" height="243" src="{{srcUrl}}" frameborder="0" allowfullscreen></iframe>',
replace: true,
controller: function($scope, $sce) {
$scope.srcUrl = $sce.trustAsResourceUrl("https://www.youtube.com/embed/" + $scope.videoId);
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-sanitize.min.js"></script>
<my-directive video-id="8aGhZQkoFbQ" width="432" height="243"></my-directive>
Upvotes: 1
Views: 623
Reputation: 27023
Your url needs to be wrapped around $sce.trustAsResourceUrl(YOUR_URL)
Add a controller
to your directive
angular.module("myModule", ['ngSanitize'])
.directive("myDirective", function() {
.....
controller: function($scope, $sce) {
$scope.iframeUrl = 'https://www.youtube.com/embed/' + $scope.videoId;
$scope.iframeUrl = $sce.trustAsResourceUrl($scope.iframeUrl);
},
template: '<iframe src="{{ iframeUrl }}" frameborder="0" allowfullscreen></iframe>'
})
Upvotes: 3