AngularJS multiple expressions concatenating in interpolation with a URL
Solution 1:
An alternative to @tasseKATT's answer (which doesn't require a controller function) is to use string concatenation directly in the expression a filter:
angular.module('myApp')
.filter('youtubeEmbedUrl', function ($sce) {
return function(videoId) {
return $sce.trustAsResourceUrl('http://www.youtube.com/embed/' + videoId);
};
});
<div ng-src="{{ video.id.videoId | youtubeEmbedUrl }}"></div>
I've found this particularly useful when using SVG icon sprites, which requires you to use the xlink:href
attribute on the SVG use
tag - this is subject to the same SCE rules. Repeating the controller function everywhere I needed to use a sprite seemed silly so I used the filter method instead.
angular.module('myApp')
.filter('svgIconCardHref', function ($sce) {
return function(iconCardId) {
return $sce.trustAsResourceUrl('#s-icon-card-' + iconCardId);
};
});
<svg><use xlink:href="{{ type.key | svgIconCardHref }}"></use></svg>
Note: I had previously tried just simple string concatenation inside the expression. However this led to some unexpected behaviour where the browser would interpret the expression before Angular had a chance to parse it and replace with the real href
. Since there is no ng-src
equivalent for the use
tag's xlink:href
I opted for the filter, which seems to have solved the issue.
Solution 2:
Since 1.2 you can only bind one expression to *[src], *[ng-src] or action. You can read more about it here.
Try this instead:
In Controller:
$scope.getIframeSrc = function (videoId) {
return 'https://www.youtube.com/embed/' + videoId;
};
HTML:
ng-src="{{getIframeSrc(video.id.videoId)}}"
Note that you still need to whitelist it as you have, or you will get locked loading resource from url not allowed by $sceDelegate policy
.
Solution 3:
in controller:
app.filter('trustAsResourceUrl', ['$sce', function ($sce) {
return function (val) {
return $sce.trustAsResourceUrl(val);
};
}]);
in html:
ng-src="('https://www.youtube.com/embed/' + video.id.videoId) | trustAsResourceUrl"