angularjs ng-repeat with filter and track by $index not working

13,974

That is because you are using the filter expression wrongly. You are using it as expression for angular built-in filterFilter. Instead you want to use your filter as is, because using it as expression you would need to modify the original array (3rd argument in the filter expression function).

Instead change:

 ng-repeat="video in videosJSON.videos.name | filter:videoUrl

to

 ng-repeat="video in videosJSON.videos.name | videoUrl 

Do:-

   <video ng-repeat="video in videosJSON.videos.name | videoUrl track by $index" preload="metadata" ng-src="{{video}}" type="video/webm">      
   </video>

and your filter evaluator should be

var videoUrl=function(names){
    if(!angular.isArray(names)){ return []; }

    return names.map(function(name){
        return "./videos/"+name;
    });  
}

Plnkr with stub data

PS: Since this seems more like a formatting filter that resolves the url it is better to use it in the controller and update the url in the view model itself rather than placing the DOM filter(filter on the view) which will be more expensive.

Share:
13,974
user3152041
Author by

user3152041

Updated on June 08, 2022

Comments

  • user3152041
    user3152041 over 1 year

    im trying to put some videos, which name is located in this json file, inside a div, this is the json file:

    {
        "videos": {
            "name": [
                "dfg.webm",
                "fdgh.mp4"
            ]
        }
    }
    

    this is the script:

    (function(){
        var app=angular.module("index",[]);
    
        var videoUrl=function(name){
            alert("asd");
            return "./videos/"+name;
        };  
        app.filter('videoUrl',function(){alert("asd");return videoUrl;});
    
        var mainController=function($scope,$http){
           var videosSuccess=function(response){
               $scope.videosJSON=response.data;         
           };
           var videosError=function(response){};
           $http({
               method: 'GET',
               url: "http://192.168.1.66/videos.json",
           }).then(videosSuccess,videosError);
        };
        app.controller("mainController",["$scope","$http",mainController]);
    
    }());
    

    and this is the html:

    <html lang="es" ng-app="index">
        <head>
        ...
        </head>
        <body ng-controller="mainController">
            <div id="videosdiv">
                <video ng-repeat="video in videosJSON.videos.name | filter:videoUrl track by $index" preload="metadata" ng-src="{{video}}" type="video/webm">      
                </video>
            </div>
    
        </body>
    </html>
    

    the problem is that the browser is rendering this:

    <video data-ng-repeat="video in videosJSON.videos.name | filter:videoUrl track by $index" preload="metadata" ng-src="dfg.webm" type="video/webm" class="ng-scope" src="dfg.webm">
    </video>
    <video data-ng-repeat="video in videosJSON.videos.name | filter:videoUrl track by $index" preload="metadata" ng-src="fdgh.mp4" type="video/webm" class="ng-scope" src="fdgh.mp4">      
    </video>
    

    instead of this:

    <video ng-repeat="video in videosJSON.videos.name track by $index" preload="metadata" ng-src="./videos/dfg.webm" type="video/webm" class="ng-scope" src="./videos/dfg.webm">      
    </video>
    <video ng-repeat="video in videosJSON.videos.name track by $index" controls="" preload="metadata" ng-src="./videos/fdgh.mp4" type="video/webm" class="ng-scope" src="./videos/fdgh.mp4">      
    </video>
    

    i think that the filter is not being used since the alert inside the function "videoUrl" is not triggered nor the "ng-src" or "src" properties are transformed... can somebody tellme what is happening or what did i do wrong? thanks