Multiple AngularJS expressions concatenating in interpolation with URL

I know this is a long time, but please carry me. The problem is easy to understand, it just takes writing to fully explain it.

I am getting this error now

Error: [$interpolate:noconcat] Error while interpolating: Strict Contextual Escaping disallows interpolations that concatenate multiple expressions when a trusted value is required. See http://docs.angularjs.org/api/ng.$sce 

I read everything in the documentation, but I still cannot find a workaround for my problem.

I use $ http.get in a private online source that has data similar to the json file form (so I cannot modify the data). The data is as follows:

 ... "items": [ { "kind": "youtube#searchResult", "etag": "\"N5Eg36Gl054SUNiWWc-Su3t5O-k/A7os41NAa_66TUu-1I-VxH70Rp0\"", "id": { "kind": "youtube#video", "videoID": "MEoSax3BEms" }, }, { "kind": "youtube#searchResult", "etag": "\"N5Eg36Gl054SUNiWWc-Su3t5O-k/VsH9AmnQecyYBLJrl1g3dhewrQo\"", "id": { "kind": "youtube#video", "videoID": "oUBqFlRjVXU" }, }, ... 

I am trying to interpolate the videoId of each element in my HTML iframe, which includes a YouTube video. In my controller.js file, I set the promise object after $ http.get as such

 $http.get('privatesource').success(function(data) { $scope.videoList = data.items; }); 

So, now the variable $ scope.videoList is mapped to data.items, which has a lot of video elements. In my HTML file, I can get the video id of each video using

 <ul class="videos"> <li ng-repeat="video in videoList"> <span>{{video.id.videoID}}</span> </li> </ul> 

and it lists all the video IDs. But if I try to associate these values ​​with a url like https://youtube.com/embed/ , this will not work.

 <div ng-repeat="video in videoList"> <iframe id="ytplayer" type="text/html" width="640" height="360" ng-src="https://www.youtube.com/embed/{{video.id.videoId}}" frameborder="0" allowfullscreen></iframe> </div> 

Is there a way I can get the videoID to interpolate to youtube url? I tried using the whitelist using $ sceDelegateProvider as follows, but it still does not work.

 $sceDelegateProvider.resourceUrlWhitelist([ 'self', 'https://www.youtube.com/**']); 

Any help is appreciated. Thank!

+43
javascript angularjs youtube concatenation interpolation
May 01 '14 at 9:31
source share
4 answers

Starting from 1.2, you can only attach one expression to * [src], * [ng-src] or to an action. You can read about it here .

Try this instead:

In the controller:

 $scope.getIframeSrc = function (videoId) { return 'https://www.youtube.com/embed/' + videoId; }; 

HTML:

 ng-src="{{getIframeSrc(video.id.videoId)}}" 

Please note that you still need to whiten it at your discretion, or you will get locked loading resource from url not allowed by $sceDelegate policy .

+56
May 01 '14 at 11:19
source share

An alternative to @tasseKATT's answer (which does not require a controller function) is to use string concatenation directly in the filter expression :

 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 found this especially useful when using SVG icon sprites, for which you need to use the xlink:href attribute in the SVG use tag - this applies to the same SCE rules. Repeating the controller function wherever I needed to use a sprite seemed dumb, so I used the filter method.

 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 previously tried just simple string concatenation inside an expression. However, this led to unexpected behavior when the browser interpreted the expression before Angular was able to parse it and replace it with a real href . Since the equivalent of ng-src for the use xlink:href tag, I chose a filter that seems to solve the problem.

+72
Jul 17 '14 at 15:35
source share

in the 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" 
+1
May 17 '17 at 12:42
source share

My version of angular.min.1.5.8.js I had the same form problem. I resolved it by changing the action = URL attribute at ng-action = URL.

0
Dec 08 '17 at 12:16
source share



All Articles