-3

I have an array of objects:

[
  {
      "id": "1",
      "LB1": "Kod produktu: PMPSB216IN80",
      "Type": "Figurki"
  },
  {
      "id": "2",
      "Type": "Głowa Do Stylizacji"
  },
  {
      "id": "3",
      "LB1": "Kod produktu: 97834",
      "Type": "Pluszak"
  },
]

Than I'm defining a string: '97834'

And I want to filter the array based on LB1 value:

filteredProducts = productList.filter(product => product.LB1.replace('Kod produktu: ', '').toLowerCase() === this.props.searchTerm.toLowerCase());

However as you can see above - not all objects contain this LB1 - and the function is throwing an error:

Test.js:101 Uncaught TypeError: Cannot read properties of undefined (reading 'replace')
Maik Lowrey
  • 15,957
  • 6
  • 40
  • 79
  • 2
    And the problem is? Just add an `if` that tests for the existence of that property before replacing... – Andreas Jan 02 '22 at 13:30

2 Answers2

2

Check to see if LB1 exists - if it doesn't, filter it out as if it didn't match your search term (here I'm using logical AND:

filteredProducts = productList.filter(product => product.LB1 != null && product.LB1.replace('Kod produktu: ', '').toLowerCase() === this.props.searchTerm.toLowerCase());
Brendan Bond
  • 1,737
  • 1
  • 10
  • 8
  • And if `product.LB1 === 0`? – Clive Jan 02 '22 at 13:35
  • Fair point @Clive! It should read `product.LB1 != null` to check for null and undefined – Brendan Bond Jan 02 '22 at 13:38
  • If you wanna get technical (and let’s face it, we do here), that’s also not right. A value of `null` means the property is set. For robust code, use `typeof product.LB1 !== ‘undefined’` for that approach. Using `in` or optional chaining are arguably both more readable – Clive Jan 02 '22 at 13:49
  • Definitely see where you're coming from here. I'm curious, though, what would you say to the argument that merely checking for nullish here (even 0) would meet our requirement of filtering out objects that don't contain a string property for LB1? Won't we get a TypeError that `replace` is not a function? – Brendan Bond Jan 02 '22 at 13:58
  • I guess we'd get that anyway if `product.LB1 === 1`, say, so moot point I suppose – Brendan Bond Jan 02 '22 at 14:01
  • Yeah I see your point but at the same time the OP only mentions _not all objects contain this LB1_. Nothing mentioned about objects with the property but with an undesired value – Clive Jan 02 '22 at 14:02
2

You could add a condition, in your filter function, that checks for the existance of that property. Here, i'm using the in operator, to validate just that.

const productList = [
  {
      "id": "1",
      "LB1": "Kod produktu: PMPSB216IN80",
      "Type": "Figurki"
  },
  {
      "id": "2",
      "Type": "Głowa Do Stylizacji"
  },
  {
      "id": "3",
      "LB1": "Kod produktu: 97834",
      "Type": "Pluszak"
  },
]

const searchTerm = '97834' /*  this.props.searchTerm.toLowerCase() */;

const filteredProducts = productList.filter(product => 'LB1' in product && product.LB1.replace('Kod produktu: ', '').toLowerCase() === searchTerm );

console.log('output', filteredProducts);
Nicolas
  • 8,077
  • 4
  • 21
  • 51