[Fixed] How to filter a list of invoices that contains a "TV" item in its nested List of items- using TypeScript

Issue

I have an array of "Invoices" object. and Within this array ,there is a nested array of "Items".
Example:

[
   {
      "invoiceNo":"10",
      "customerId":"101",
      "invoiceTotal":"2500",
      "items":[
         {
            "itemId":"1",
            "itemName":"TV"
         },
         {
            "itemId":"2",
            "itemName":"Laptop"
         },
         {
            "itemId":"3",
            "itemName":"PC"
         }
      ]
   },
   {
      "invoiceNo":"11",
      "customerId":"102",
      "invoiceTotal":"7500",
      "items":[
         {
            "itemId":"2",
            "itemName":"Laptop"
         },
         {
            "itemId":"3",
            "itemName":"PC"
         }
      ]
   }
]

I want to return only array of all invoices that contains "TV" item.

The following is my code

let text = queryText.toLowerCase();
    return this.http
      .get<Invoices[]>(
        this.url + "/crm-operations/application/invoices",
        { headers: headerInfo }
      )
      .pipe(
        map((invoicesData) =>
        invoicesData.filter((invoice) => {
            if (invoice.items) {
              invoice.items.filter((row) => { 
                 row.itemName.toLowerCase().indexOf(text)>-1;
              });
            }
          })
        )
      );

The result is always an empty array
IT must return an array with the invoice number "10" object.
What is wrong is my code. and is there another way to solve this problem?

Solution

change the body of your map operator to this:

invoicesData.filter((invoice) =>
  // (1)
  invoice.items?.some((row) => // (2)
    // (3)
    row.itemName.toLowerCase().indexOf(text)>-1
  )
)

(1) removes curly braces to return the value (true/false) of invoice.items?.some(..)

(2) instead of filter we use some. It’s a bit more efficient since it doesn’t iterate over all remaining array items once the inner function returns true for some item.

(3) removes curly braces to implicitly return the result of row.itemName.toLowerCase().indexOf(text)>-1

Leave a Reply

(*) Required, Your email will not be published