Issue with Angular 2 pipe causing unexpected undefined result

Here is a JSON format that I am working with:

[{
  "id": 9156,
  "slug": "chicken-seekh-wrap",
  "type": "dish",
  "title": "Chicken Seekh Wrap",
  "cuisine_type": [2140]
},
{
  "id": 9150,
  "slug": "green-salad",
  "type": "dish",
  "title": "Green Salad",
  "cuisine_type": [2141]
}]

In my Angular2 project, I have created a pipe for filtering by cuisine type:

@Pipe({
      name: 'filter',
      pure: false
 })
 export class FilterPipe implements PipeTransform {
     transform(list: Array<any>, searchTerm: any): Array<any> {
        if(!searchTerm) return list;
        else {
           return list.filter(item => item.cuisine_type[0] == searchTerm);
        } 
     }
 }

I have implemented the pipe in my view like this:

<li *ngFor="let dish of dishes | filter : 2140">
      <h2>{{dish.title}}</h2>
      <input type="checkbox" [formControlName]="dish.id" />
 </li>

However, I encountered the following errors:

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'filter' of undefined
TypeError: Cannot read property 'filter' of undefined
    at FilterPipe.transform (filter.ts:20)
    at checkAndUpdatePureExpressionInline (core.es5.js:11241)
    at checkAndUpdateNodeInline (core.es5.js:12096)
    at checkAndUpdateNode (core.es5.js:12058)
    at debugCheckAndUpdateNode (core.es5.js:12687)
    at debugCheckDirectivesFn (core.es5.js:12628)
    at Object.View_FourthStepPage_1.currVal_0 [as updateDirectives] (FourthStepPage.html:26)

I would appreciate any help or guidance on what I might be doing wrong. Thank you.

Answer №1

To start, make sure to eliminate the unnecessary ')' at the end of your *ngFor loop. Next, the error is occurring because you are passing null to your filter function. When the filter tries to operate on null, it causes an error since you cannot filter null values. I recommend adding a validation check to ensure that the value being passed is valid. You can update your pipe like this:

@Pipe({
      name: 'filter',
      pure: false
 })
 export class FilterPipe implements PipeTransform {
     transform(list: Array<any>, searchTerm: any): Array<any> {
        if(!list)
          return [];
        if(!searchTerm) return list;
        else {
           return list.filter(item => item.cuisine_type[0] == searchTerm);
        } 
     }
 }

By doing this, you prevent filtering undefined values.

P.S If your data is fetched from a remote server and dishes are stored as observables, you will also need to use the async pipe.

Answer №2

If you are receiving data from a backend source, it's possible that the list has not been fetched yet and your variable is currently undefined. In this situation, there are two recommended solutions to consider.

Approach 1

Instead of verifying the list within your pipe function, it's best practice to avoid this method as it goes against good software practices. Placing additional logic in the pipe can lead to functions becoming overly complex and difficult to maintain.

Best Practice Tip:

The responsibility of the pipe should solely focus on transforming the data without any additional checks or validations. Following the Single Responsibility Principle (SRP) helps in creating cleaner and more efficient codebase.

A preferable approach would be to sanitize the data before transformation by initializing the list with an empty array [].

Approach 2

To ensure smooth functioning, either have the list start off as empty or prevent the *ngFor directive from executing initially. This can be achieved by using *ngIf to hide the element until the data is ready to be displayed.

Answer №3

This syntax is unfamiliar to me... You may want to attempt the following:

<ul *ngFor="let item of items | filter : 2140">

Answer №4

There seems to be an additional ")" in this code snippet after 2140

*ngFor="let dish of dishes | filter : 2140)"
. Simply remove it and give it a try, I have personally tested this fix and can confirm that it works as intended.

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

What is the best way to organize code into separate files while utilizing a module that needs to be included in every file?

In this particular scenario, I am utilizing a headless browser with Puppeteer Chrome and MongoDB. Take a look at the following code snippet: var browser = await puppeteer.launch() var page = await browser.newPage() var db = await MongoClient.connect(" ...

The functionality of AJAX is hindered in the browser when attempting to fetch data from a URL

Lately, I've been encountering a strange issue when trying to fetch data from a URL. $.ajax({ url: 'URLHERE', dataType: 'html', success: function(data) { //function 2 var xml = $.parseXML(data) $(xml).find('StopLoca ...

What is the proper way to include jQuery script in HTML document?

I am facing an issue with the banners on my website. When viewed on mobile devices, the SWF banner does not show up. In this situation, I want to display an <img> tag instead, but the jQuery code is not functioning correctly. My template structure l ...

Creating dynamic keys using Typescript and JSON data format

Currently, I am developing an application using Typescript and React Native. Within my app, I have a JSON file containing information about poker hands that needs to be accessed. The structure of the JSON data is as follows: { "22": [ [ ...

Executing a NestJs cron job at precise intervals three times each day: a guide

I am developing a notifications trigger method that needs to run three times per day at specific times. Although I have reviewed the documentation, I am struggling to understand the regex code and how to customize it according to my requirements! Current ...

How can I retrieve the length of an array in vuejs?

This snippet includes a script tag <script> export default { data() { return { blogs: [], }; }, created() { this.paginate_total = this.blogs.length / this.paginate; }, }; </script> Displayed below is the respo ...

Tips on how to retrieve the current value of a scope variable in jQuery

When making a $http request to save data on the server and receiving a json response, I want to show an Android-style message using Toast for either success or failure based on the response. Initially, I set a scope variable to false $scope.showSuccessToa ...

Add() function is not duplicating the formatting

I'm attempting to replicate the content below inside a DIV. <ul class="pie-legend"><li><span style="background-color:#0066CC"></span>10-0-1</li><li><span style="background-color:#33CC33&q ...

Replicate the ctrl+/- function through coding

While browsing with your browser, you have the ability to adjust the font size by using CTRL + + or CTRL + -. Is there a way to replicate this functionality through code, such as with JavaScript? I am looking to add buttons on my website that allow users ...

Error: The `Field` component encountered a failed prop type validation due to an invalid prop `component` after upgrading to MUI version

Encountered an error when migrating to Material ui v4 Failed prop type: Invalid prop component supplied to Field. in Field (created by TextField) This error points to the redux form field component export const TextField = props => ( <Field ...

Form control identifier and input field name

I am currently developing a custom input feature for my application. One of the functionalities I want to include is auto-completion, and in my research, I found out that certain conditions need to be met for it to work: In order to enable auto-completi ...

Can the ajaxsetup error handler be used with the POST method?

I have a strange question - does the global error handler applied when using ajaxsetup get triggered in case of an Ajax error on a POST request? I've tried handling Ajax errors in several places, but the error handler is only being hit for GET reques ...

Implementing hashing with resumable.js

Looking for a way to include hashing in resumable.JS by utilizing the "fileAdded" event hook. Any suggestions on how to add hash to each chunk? ...

Using jQuery or JavaScript to clear multiple selections in a multiselect dropdown when a button is clicked

Is there a way to clear the dropdown selections once my function saves data to local storage? You can refer to this fiddle for more details: http://jsfiddle.net/3u7Xj/139/ I already have code in place to handle other form elements: var $form = $("#formI ...

Angular 14 Custom Validator Assistance

I need help understanding how to incorporate a custom validator in my reactive form. I have 15 fields, and 3 of them are related to the custom validators "tcpPorts", "udpPorts", and "icmp" (a checkbox). The requirement is that at least one of these three f ...

the deactivation of my rollover class is being caused by my float class

With the assistance of a generous contributor on stackoverflow, I was able to overlay different colored CSS boxes onto various images. These boxes could be removed upon mouseover, revealing the images beneath. You can view the code I used on fiddle here. ...

Executing an npm task from a JavaScript file in a parent/child process scenario

As someone who is still learning about child-process, I need some additional clarification on the topic. The Situation I am trying to find a way to execute one js file as a separate process from another js file. I want to pass a specific argument (a numb ...

To utilize the span and input text increment functionality, simply use the required input type number and hold either the up or down arrow

Is it possible to increment the value of an input type number by 1 when holding down on a mobile device? <input type="text" id="number" value="1"> <span id="upSpan"> Up </span> $('#upSpan').on('touchstart', function ...

Angular service providing a subset of resource data

I am currently working with an Angular factory called DogePrice: .factory('DogePrice', ['$resource', function ($resource) { return $resource("https://chain.so/api/v2/get_info/DOGE"); }]) Usually, the API response looks like this: ...

Is there a way to identify modifications in an Object and an Array when utilized as Input attributes in a sub-component?

After exploring the following two questions, I found that there weren't any helpful answers: Detect change in object of input array Detect changes in component input when it is a object In my current scenario, I am faced with the need to pass variou ...