Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular JS dynamic ng-src not working in 1.2.0-rc.2

I'm trying to implement a video element in an angular JS app and the ng-src won't read the scope variable

I'm using 1.2.0-rc.2

<!DOCTYPE html>
<html ng-app="ngView">

<head>
   <script src="http://code.angularjs.org/1.2.0-rc.2/angular.min.js"></script>

   <script>
   var app = angular.module('ngView', []);
   function MyControl($scope){
      $scope.file = '1234.mp4';
   }
  </script>
  </head>
  <body ng-controller="MyControl">
      <video controls  ng-src="http://www.thebigdot.com/{{file}}"></video>
  </body>
</html>

If I use a much older version AngularJS lib, it works.

cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.3/angular.min.js (works)

Is this a bug in the latest release or has it been disabled on purpose? What is the work around ?

like image 269
Ajq Avatar asked Oct 15 '13 02:10

Ajq


3 Answers

Angular 1.2 ships with Strict Contextual Escaping (SCE) enabled by default. You need to tweak your code slightly to make it work.

HTML

Change the markup so that the ng-src binds to a variable and not a URL + variable as you had it setup before:

<video controls ng-src="{{videoUrl}}"></video>

JavaScript

Add $sce to inject the SCE provider and use the $sce.trustAsResourceUrl method to set videoUrl.

function MyControl($scope, $sce) {
    var videoUrl = 'http://www.thebigdot.com/1234.mp4';
    $scope.videoUrl = $sce.trustAsResourceUrl(videoUrl);
}

Here's a JS Bin demo of this setup in action.

like image 154
Ahmad Mageed Avatar answered Nov 19 '22 03:11

Ahmad Mageed


after a bit of debugging I found that the error is this:

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

http://errors.angularjs.org/1.2.0-rc.2/$interpolate/noconcat?p0=http%3A%2F%2Fwww.thebigdot.com%2F%7B%7Bfile%7D%7D
    at http://code.angularjs.org/1.2.0-rc.2/angular.js:78:12
    at $interpolate (http://code.angularjs.org/1.2.0-rc.2/angular.js:6953:17)
    at attrInterpolateLinkFn (http://code.angularjs.org/1.2.0-rc.2/angular.js:5367:27)
    at nodeLinkFn (http://code.angularjs.org/1.2.0-rc.2/angular.js:5121:13)
    at compositeLinkFn (http://code.angularjs.org/1.2.0-rc.2/angular.js:4640:15)
    at nodeLinkFn (http://code.angularjs.org/1.2.0-rc.2/angular.js:5115:24)
    at compositeLinkFn (http://code.angularjs.org/1.2.0-rc.2/angular.js:4640:15)
    at compositeLinkFn (http://code.angularjs.org/1.2.0-rc.2/angular.js:4643:13)
    at publicLinkFn (http://code.angularjs.org/1.2.0-rc.2/angular.js:4549:30)
    at http://code.angularjs.org/1.2.0-rc.2/angular.js:1157:27 <video controls="" ng-src="http://www.thebigdot.com/{{file}}"> angular.js:7861

this article explains what is going on and how to disable the Strict Contextual Escaping: http://docs.angularjs.org/api/ng.$sce

like image 37
akonsu Avatar answered Nov 19 '22 05:11

akonsu


I build this directive

app.directive('loadAudio', function($parse) {
  return {
    restrict: 'EA',
    scope: {
        source: '=',       
    },
    template: '<audio />',
    link: function(scope, iElement, iAttrs) {

      scope.$watch('source', function(value) {
        var audio = iElement.find('audio');

        audio.attr('src',  value);
      }, true);
    }
  }
});

And next is what I write on the template

<load-audio source="your_src" ></load-audio>
like image 27
Tuan Bach Van Avatar answered Nov 19 '22 05:11

Tuan Bach Van