What is the reason behind Angular's repeat filter only being able to access its own element within the return function?

I have successfully implemented some Angular code that is working, however, I am struggling to understand why it works. Coming from a C Sharp background and being new to JS and Typescript.

<tr ng-repeat="colleague in Model.FilteredColleagueListModel | filter:Model.searchText(Model.SearchCriteria)" >

    public searchText(searchCriteria)
    {

        return function (item) {
            if (item.DisplayName.indexOf(searchCriteria) > -1 
            {
                return true;
            }
            return false;
        }  

    };

One thing that puzzles me is the nested function. Why is 'item' only available within the return function? Also, I'm not sure if returning a function like this is the correct approach in TypeScript. Is it acceptable to ask more open-ended questions like these?

Answer №1

The current pattern being utilized is a stateful filter, which is not recommended. To learn more, please visit https://docs.angularjs.org/api/ng/filter/filter.

It is strongly advised against writing stateful filters as Angular struggles to optimize their execution, potentially causing performance issues. Stateful filters can often be transformed into stateless filters by exposing the hidden state as a model and incorporating it as an argument for the filter.

Consider making the searchCriteria an argument for the returned function. This way, the syntax would look something like

filter:Model.searchText:Model.SearchCriteria

public searchText()
{

    return function (item, searchCriteria) {
        if (item.DisplayName.indexOf(searchCriteria) > -1 
        {
            return true;
        }
        return false;
    }  

};

Answer №2

The functionality of this code is remarkably similar to JavaScript's 'array.filter(). It wouldn't be surprising if it's actually utilizing that under the surface.

The process involves your searchText method receiving the search criteria and being invoked. This method is then utilized by Angular's filter on each element within your collection, passing that specific element to it.

If you were to console.log(item);, you'd notice that it doesn't display the entire array but rather each individual item. When your returned method evaluates to true, Angular retains that particular item; however, if it evaluates to false, Angular discards it. This mirrors the behavior of the native filter function. Therefore, your anonymous function is not just called once, but for every item in the array.

I cannot provide insight into the syntax and workings related to TypeScript, but returning a method is indeed the correct approach to implementing this functionality, akin to how one would use a native array.filter().

EDIT: I have included the Fiddle link I used to double-check my observations, in case anyone is interested: http://jsfiddle.net/wf5shz70/

EDIT: @jonas raised an excellent and significant point regarding stateful filters, which I overlooked.

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

Is there a way to organize this array based on the group score?

0: {id: 2575, groepName: "ezeez-1", groupScore: 50, Players: Array(0)} 1: {id: 2574, groepName: "ezeez-2", groupScore: 25, Players: Array(0)} 2: {id: 2576, groepName: "ezeez-3", groupScore: 10, Players: Array(0)} 3: {id: 2577, ...

Is mocking all dependencies in an AngularJS controller necessary for unit testing?

Is it necessary to mock all the dependencies of my controller in order to test the scope? Here is a snippet of my code... .controller('SignupCtrl', ['$scope', 'vcRecaptchaService', '$http', '$location', & ...

Incorporate a new style into several previous slides using the Slick carousel feature

I'm attempting to utilize the Slick carousel to create a timeline. My goal is for the previous slides to remain colored as you progress through the timeline, and turn grey when you go back. I've tried using onAfterChange and onBeforeChange, but I ...

Perform an asynchronous request using a data variable retrieved from a previous asynchronous request

I have a function using ajax to parse XML data. Here is an example: $.ajax({ type: "GET", url: "the.xml", dataType: "xml", success: function parseXml(data){ $(data).find("ITEM").each(function(){ var x = $("URL", this).t ...

AngularJS: Add a unique CSS class to the initial item within an ng-repeat directive

I am searching for the initial index that meets my ng-if condition, which is not always equal to $index === 0, and cannot be resolved using $first. Below is a snippet of my code: <div class="ticket-event" ng-if="!item.hidden" ng-repeat="item in ctrl.e ...

Is It Best to Override Behavior in a Directive?

Having two directives that display lists of documents, one for user-favorited documents and the other for user-pinned documents. The criteria for displaying these documents depend on the values of "pinned" and "favorite" within each document object: docum ...

Retrieve the latency of the interaction.reply() method

While there have been many inquiries regarding how to create a ping command for a discord.js bot, my question stands out because I am attempting to develop this command for interaction rather than message. I attempted utilizing Date.now() - interaction.cre ...

Exploring Vue's data binding with both familiar and mysterious input values

How can I model an object in Vue that contains both known and unknown values? The quantity is unknown, but the type is known. I need to present user inputs for each type, where the user enters the quantity. How should I approach this? data() { retur ...

Can double curly braces be added within an HTML attribute when using Vue?

Suppose I would like to include <input value='{{default}}'></input> in regular HTML. This will display a textbox with {{default}} as the default input. However, when attempting to achieve the same thing with Vue, it does not work as ...

Having trouble with Django's submit POST method for creating objects

Latest Updates: I have successfully implemented a feature where the page does not reload upon clicking the submit button. To achieve this, I filled out the form and inspected the page source code. The form structure was as follows: The corresponding sou ...

When using Node.js, the process.exit() function will not terminate if there is an open createReadStream

My program interacts with Asterisk using EAGI, where Asterisk communicates with my Node.js application by sending data via STDIN and receiving commands via STDOUT. When a user ends the call, the Node.js process receives a SIGHUP signal for clean terminatio ...

Tips for effectively dividing React application components

Jumping into React to build an application seemed like a good idea at first, but now I realize the complexity of it. Let me walk you through my plan and see if it aligns with best practices: The goal is to develop a React App for organizing the subjects I ...

Is it possible to pass a component into a dialogue box in material-ui using React?

Hello, I am currently facing an issue with displaying a chart component within a dialogue box. Despite having the code in place, the chart is not rendering inside the dialogue box as expected. Unfortunately, due to the complexity of the code, I am unable t ...

Show an array of arrays using a visual table representation

I am working with an Array of arrays in my data, and they are structured like this : https://i.sstatic.net/3grh6.png Now, I am trying to showcase this array in a table, but all I am getting is a blank page. Here is the HTML code for the table (I have incl ...

Customize Bootstrap radio buttons to resemble standard buttons with added form validation styling

Is there a way to style radio buttons to look like normal buttons while maintaining their functionality and form validation? I have two radio buttons that need styling but should still behave like radio buttons. Additionally, I am utilizing Bootstrap for s ...

How can socket listener be dynamically added in node.js with socket.io?

Assuming you have a basic socket.io configuration set up: var app = require('http').createServer().listen(80,'127.0.5.12'), io = require('socket.io').listen(app); session = require('./local_modules/session.js'); / ...

Javascript, removeFromString

I'm currently working on a JavaScript function that takes in two strings. The first string is any sentence provided by the user, and the second string consists of letters to be removed from the original sentence. My approach involves converting both s ...

Typescript: issue with type guard functionality not functioning properly

type VEvent = { type: "VEVENT"; summary: string; }; type VCalendar = { type: "VCALENDAR"; }; const data: Record<string, VEvent | VCalendar> = (...); array.map((id) => { return { id, title: dat ...

Tips for updating form values with changing form control names

Here is an example of a form I created: public profileSettingsGroup = new FormGroup({ firstName: new FormControl('Jonathon', Validators.required) }) I also have a method that attempts to set control values in the form: setControlValue(contro ...

The promise object is displayed instead of the actual data retrieved from the API call

I am currently working on fetching data from an API and showcasing the name of the returned data on the front end. This function successfully retrieves the data through an API call: async function retrieveData(url){ var _data; let response = await fetch( ...