Reputation: 53826
Here I'm attempting to extend the standard text filter to perform a get request and pass value to extended filter user has entered
The filter name is 'search' :
myapp.filter('search', function($filter){
console.log('search param'+$scope.search)
$http.get('http-hello2.html').success(function (data) {
return $filter;
});
But receive error :
Error: [$http:badreq] http://errors.angularjs.org/1.4.9/$http/badreq?p0=undefined
at Error (native)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js:6:416
at m (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js:85:218)
at Function.c.$get.m.(anonymous function) [as get] (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js:90:109)
at link (https://run.plnkr.co/rz2TWpQpyYaVbHXN/script.js:14:27)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js:73:222
at ca (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js:73:279)
at I (https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js:62:174)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js:69:193
at https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js:119:221 <status-viewer url="sourceUrl" class="ng-isolate-scope">
How to extend standard AngularJS text filter to invoke custom functionality and pass parameter to this filter? The custom functionality should occur prior to the standard filter logic being invoked.
plnnkr : https://plnkr.co/edit/F0XsOPZKq5HArFo9vtFs?p=preview
src :
goob.html :
goob
http-hello2.html
2. http-hello2.html
test.html :
test
index.html :
<!doctype html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-controller="FetchCtrl">
<label>Filter: <input ng-model="search"></label>
<div ng-repeat="sourceUrl in sourceUrls | filter:search">
<status-viewer url="sourceUrl"> </status-viewer>
</div>
</div>
</body>
</html>
mytemplate.html :
<!--<h1>{{url}}</h1>-->
<div>
<p>{{model}}</p>
</div>
script.js :
var myapp = angular.module('app', []).controller('FetchCtrl', FetchCtrl)
myapp.directive('statusViewer', function ($http , $interval) {
return {
restrict: 'E',
templateUrl: 'mytemplate.html',
scope: {
url: '='
},
link: function (scope, elem, attrs, ctrl) {
scope.isFinishedLoading = false;
$http.get(scope.url).success(function (data) {
scope.model = data;
});
}
};
});
myapp.filter('search', function($filter){
console.log('search param'+$scope.search)
$http.get('http-hello2.html').success(function (data) {
return $filter;
});
});
function FetchCtrl($scope, $http, $q , $parse) {
$scope.sourceUrls = [
'http-hello2.html',
,'test.html'
,'goob.html'];
}
Upvotes: 3
Views: 163
Reputation: 136154
Error comes out because initially you had no value in
$scope.search
value and url has passed asundefined
, other thing is you were tried to use$scope
inside filter, which can't be accessible
As I can see that you don't wanted to load some template on change of input value. And from your current approach you wanted to load template from filter based on input(if I understood it correctly). But it seems like you are on wrong track.
Basically filtering is used to do some manipulation on binding while showing some value(like showing normal word in uppercase will use uppercase filter). Here you are using the filter for loading template on input change
(basically that would fire a filter but not because of input change, it fires on digest cycle). Every time digest cycle will run it will make an ajax to fetch that template. Technically angular filter is not meant for what you are doing there.
Extending text filter turns out to be wrong approach as you don't need to extend it.
Better I'd say you should put ng-change
event on input field with some function, that will fire up that function on each input change. and it will not make any change in filter working. By making this changes this would make template call only when input is changed
Markup
<input ng-model="search" ng-change="change()" />
Code
$scope.change = function() {
//code here.
};
Upvotes: 0
Reputation: 26196
First of all you need to inject $http Service into you filter to prevent error that you have:
myapp.filter('search', function($filter, $http){
and second thing:
you should not do
$http.get(scope.url)
not being sure that scope.url
is already set.
I would suggest to do request by condition;
if(scope.url){
//$http.get(scope.url)...
}
Upvotes: 1