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

Confirm the Text Box with JavaScript

I'm struggling with validating the textbox on my login Xhtml. Once I finally cracked the code, I encountered an issue with the 'container' class in the section. How can I properly write the code and successfully validate the textbox? <h ...

Error Uncovered: Ionic 2 Singleton Service Experiencing Issues

I have developed a User class to be used as a singleton service in multiple components. Could you please review if the Injectable() declaration is correct? import { Injectable } from '@angular/core'; import {Http, Headers} from '@angular/ht ...

JavaScript prototypal inheritance concept

During my free time, I like to dabble in JavaScript, but I’m currently struggling with this particular topic. var person = new Person("Bob", "Smith", 52); var teacher = new Teacher("Adam", "Greff", 209); function Humans(firstName, lastName) { this. ...

Search the table for checked boxes and textboxes that are not empty

Could you suggest alternative ways to express the following scenario? I have a table with 3 rows. Each row contains a column with 3 checkboxes and another column with just a text box. I would like it so that when the values are retrieved from the database ...

How can I test for equality with an array item using v-if in Vue.js?

Currently, I am facing a challenge in my Vue.js project where I need to determine if a number is equal to an element within an array. Here is the code snippet that I am working with: <div v-if="someValue != arrayElement"> // </div> I am st ...

Unable to display image on React page using relative file path from JSON data

Greetings, this is my initial post so please forgive me if I have missed any important information. I'm currently in the process of creating a webpage using react. My goal is to display content on the page by iterating over a relatively straightforwa ...

Misplace reference to object during method execution

Here's a simple demonstration of the issue I'm facing. The count function is supposed to keep track of the number of items returned from a query. However, my current implementation causes me to lose reference to the function when calling it from ...

Why is JavaScript globally modifying the JSON object?

I have a few functions here that utilize the official jQuery Template plugin to insert some JSON data given by our backend developers into the variables topPages and latestPages. However, when I use the insertOrHideList() function followed by the renderLis ...

Troubleshooting: AngularJS not displaying $scope variables

I have a question that has already been answered, but the suggested solutions did not work for me. Everything seems to be fine, but the content within curly brackets is not displaying on screen. <div ng-controller="Hello"> <p>The I ...

Dynamically loading an AngularJS controller

I am faced with the challenge of integrating an Angular app with dynamically loaded controllers into an existing webpage. Below is a code snippet where I have attempted to achieve this based on my understanding of the API and some research: // Create mod ...

When async/await is employed, the execution does not follow a specific order

I'm curious about the execution of async/await in JavaScript. Here are some example codes: async function firstMethod(){ new Promise((resolve, reject)) => { setTimeout(() => { resolve("test1"); }, 3000); }); } async ...

What is the best way to monitor React hooks efficiently?

Prior to diving into a new React project, I always make sure that there are adequate developer tools available for support. One of my favorite features in React is the React Developer tool for Google Chrome. It allows me to examine the internal state of e ...

Error animation on client-side validation not resetting correctly

Incorporated a form validation and error display system utilizing TransitionGroup for animations. The flag issueVisible manages the visibility of the error message, while determineField() aids in identifying the field related to the error. The issue arise ...

How to surround values and keys with double quotes using regular expressions in JavaScript

I am in need of a valid JSON format to request ES. I currently have a string that looks like this: { time: { from:now-60d, mode:quick, to:now } } However, when I attempt to use JSON.parse, I encounter an error because my ...

Acquiring the specific checkbox value using JQuery

I am encountering an issue with my JQuery function that is supposed to print out the unique value assigned to each checkbox when clicked. Instead of displaying the correct values, it only prints out '1'. Each checkbox is assigned an item.id based ...

What is the best way to trigger a method once an image has completed loading and rendering?

Is there a way to trigger a method once an image has finished loading and displaying on the web browser? Here's a quick example using a large image: http://jsfiddle.net/2cLm4epv/ <img width="500px" src="http://www.digivill.net/~binary/wall-cover ...

What is the best way to allow someone to chain callback methods on my custom jQuery plugin?

My goal is to enhance the functionality of jQuery.post() by implementing a way to check the response from the server and trigger different callbacks based on that response. For instance: $("#frmFoo").postForm("ajax") .start(function () { showSpinner( ...

Can a constructor function be utilized as a parameter type in another function within TypeScript?

Recently, I came across TypeScript and after watching some video reviews, I see great potential in it. It seems to offer better code completion, implicit code documentation, and enhanced type safety for JavaScript. I'm currently in the process of con ...

The capability to scroll within a stationary container

Whenever you click a button, a div slides out from the left by 100%. This div contains the menu for my website. The problem I'm encountering is that on smaller browser sizes, some of the links are hidden because they get covered up. The #slidingMenu ...