Combining multiple AngularJS expressions to form a URL within an interpolation statement

While this explanation may be lengthy, I appreciate your patience as I try to articulate the issue at hand. The error I'm currently encountering is as follows:

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

Despite extensively reading through the documentation, I have yet to discover a solution for my predicament.

The scenario involves me utilizing $http.get on a private online source containing data structured similarly to a JSON file (data cannot be modified). Here's an example snippet of how the data appears:

...
"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"
       },
    },
...

My objective is to interpolate the videoId of each item into an HTML iframe that embeds the respective YouTube video. In my controller.js file, I'm setting the promise object after the $http.get request like so:

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

As a result, the variable "$scope.videoList" is now linked to data.items, which consists of numerous video elements. Within my HTML file, I can access the videoID for each video using:

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

This successfully displays all the video IDs. However, attempting to concatenate these values with a URL such as proves unsuccessful.

<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 to effectively interpolate the videoID into the YouTube URL? Despite trying to whitelist it using $sceDelegateProvider as shown below, the issue persists:

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

Any assistance offered would be greatly appreciated. Thank you!

Answer №1

A different approach from @tasseKATT's solution (without the need for a controller function) is utilizing 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>

This method came in handy when dealing with SVG icon sprites that require using the xlink:href attribute - which is also subject to SCE rules. Instead of repeating a controller function, I opted for the filter.

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>

Please note that attempting simple string concatenation within the expression caused unexpected browser behavior. To solve this issue, I used filters instead of relying on Angular's parsing mechanisms for specific attributes like xlink:href.

Answer №2

Starting from version 1.2, only one expression can be bound to *[src], *[ng-src], or action. More information on this change can be found here.

Here is an alternative approach:

In your Controller:

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

HTML:

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

Remember to whitelist it as before, otherwise you may encounter the error message

locked loading resource from url not allowed by $sceDelegate policy
.

Answer №3

within the controller script:

app.filter('trustAsResourceUrl', ['$sce', function ($sce) {
    return function (val) {
        return $sce.trustAsResourceUrl(val);
    };
}]);

within the html template:

ng-src="('https://www.youtube.com/embed/' + video.id.videoId) | trustAsResourceUrl"

Answer №4

Using angular.min.1.5.8.js is what I prefer. When dealing with a form problem, I found success in replacing the attribute action=URL with ng-action=URL.

Please be aware that using ng-action as a directive will not produce the desired outcome.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

KnockoutJS is unable to assign a negative value to an input field

Is there a way to assign the value of an <input> as false? It seems to work fine with true. Data Model: function DataModel(){ self = this; self.Flag = ko.observable(false); }; HTML Code: <input type="text" data-bind="value:Flag"/> ...

Retrieving entities from a text

I found a script on the Webdriver.io website that looks like this (adjusted for testing) const { remote } = require('webdriverio'); var assert = require('assert'); ;(async () => { const browser = await multiremote({ ...

Having some trouble with node.js and the fs module when checking if a file exists. Let

I'm a bit confused about the various methods in Node.js to check if a file exists using fs(). One option is to use fs.readFile(): fs.readFile('somefile.html', function (err, data) { if (err) { /* file doesn't exist */ } else { /* ...

Assigning a variable in jQuery to a PHP variable that has not been defined can halt the script

Here is the code snippet for a document ready function: $(document).ready(function(){ var id = <?php echo "" ?>; alert('boo'); if(id!=0){ $(' ...

Looking to implement a star rating feature in Vue.js 2?

My perspective is as follows : <div class="col-md-8"> ... <star-rating :value="3"></star-rating> ... </div> This is how my star-rating component looks like : <template> <span class="rating"> &l ...

Storing and retrieving objects in cookies using AngularJS

I'm having trouble retrieving the object I set in a cookie, as it's showing me [Object Object] instead. Here is the code snippet where I SET the object into the cookie: click: function (event, ui) { //other code $scope.fields = {name:true, ima ...

Ways to stop jQuery from stripping the <script> elements

Is there a way to stop jquery from removing my JS default behavior? function loadPageSuccess(data) { var data = $(data).find('#content'); alert($(data).html()); $("#content").html(data); $("#page").fadeTo(100,1); } function loadP ...

Allow editing for only a specific part of a text box

Creating a customized personal URL page for users on my site is important to me. I envision the value of a text box being "example.com/username," with the "example.com/" part displayed in the text box, but not editable. I've noticed that Tumblr accom ...

Updating the background of a div in HTML through the power of JavaScript

I am having trouble changing the background of a DIV. I believe my code is correct, but it doesn't seem to be working. I suspect the error lies with the URL parameter, as the function works without it. Here is my code: <script language="JavaS ...

changing the RadioButtonList to preselect a default value

On a page, I have a pre-existing RadioButtonList where I want to make the second button checked by default instead of the first one. Since I am unable to edit the original control directly, it seems like I might need to achieve this using javascript on th ...

Passing the index in React Native

I am currently developing a music app utilizing the react-native-track-player library. I have created three components named Clusters, Songlist, and Play. Understanding How the Screen Works The flow of components is as follows: Clusters component -> Song ...

Apply jQuery styling to new select box on page in order to maintain consistent styling throughout

I've encountered an issue with my jQuery select box styling. It appears to work perfectly on the initial page load, but when new content containing a select box is dynamically loaded onto the page, the styling doesn't get applied to it. Can anyo ...

What is the method to have the text cursor within a text field start a few pixels in?

I need a text field with the cursor starting a few pixels (let's say 4) from the left-hand side. I am aware that this can be achieved by adjusting the size of the text field using padding, but I am curious if there is a way to resize the text box with ...

Regex for US zip code with an optional format

Searching for a regular expression to validate US zip codes. I have come across multiple examples, but none of them cater to the scenario where the zip code is optional. The input field I am working on does not require a zip code, so it should accept a 5 ...

The input box is not properly filled with the complete string using protractor sendKeys

[HTTP] --> POST /wd/hub/session/ffcd7072-9f96-45cb-a61d-ec53fc696b56/element/0.9513211246393813-32/value {"value":["1","0","0","0","1"],"text":"10001"} My JavaScript code snippet: this.zipcode = element(by.model('personalInfo.zipcode')); this ...

Error: Attempting to access property 'setData' of an undefined object results in a TypeError [Slider]

I encountered an error with my slider that says Uncaught TypeError: Cannot read property 'setData' of undefined. The error occurs when I use material ui as a component along with redux-form. This issue happens specifically when the slider is bein ...

Having difficulty displaying form errors using handlebars

My form validation is not working properly. When I enter incorrect information, it alerts correctly, but when I submit the form, it returns [Object object]. What could be causing this issue in my code and how should I handle the data? https://i.stack.imgu ...

Notification for Unsuccessful Login Attempt on the Client Side

In my node.js project, I have implemented a login form that sends data to the server.js file as URL parameters. When the sent data is verified against registered users, the client is successfully logged in. However, I am facing an issue on how to notify th ...

Change the value of a single element in an array using a component in ReactJS

I'm attempting to pass an array value to a specific index in one component and then assign a desired value from the child component. I need it to work this way because I'm developing a survey app where the number of questions can vary. This is j ...

Ways to extract specific HTML from a jQuery element

When fetching html from a website, how can I extract specific html content instead of getting all of it? I have attempted the following method: Before appending data to the target below container.html(data); I would like to perform something like data.f ...