Home > Software design >  Angular - How to get objects in a nested array of objects
Angular - How to get objects in a nested array of objects

Time:07-22

In Angular-14 application, I have this JSON response:

{
  "data": {
    "pageItems": [
      {
        "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "merchantId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
        "userId": "string",
        "merchant": {
          "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
          "merchantName": "string",
          "accountNumber": "string",
          "userLists": [
            {
              "id": "string",
              "firstName": "string",
              "lastName": "string",
              "email": "string"
            }
          ]
        }
      }
    ],
  },
  "successful": true,
  "message": "string",
  "statusCode": 0
}

Then I represented it model interface as shown below:

merchant-user-list.model:

export interface IUserList {
  id: string;
  firstName: string;
  lastName: string;
  email: string;
}

export interface IMerchant {
  id: string;
  merchantName: string;
  accountNumber: string;
}

export interface IPageItem {
  id: string;
  merchantId: string;
  userId: string;
  merchant: IMerchant;
}

export interface IData {
  pageItems: IPageItem[];
}

export interface IMerchantUserList {
  data: IData;
  successful: boolean;
  message: string;
  statusCode: number;
}

However, I want to search the DB table using firstName, lastName and email. So I did this in the typescript component.

merchant-users-list.component:

import { MerchantUserService } from 'src/app/services/merchant-user.service';
import { IData, IPageItem, IMerchantUserList } from 'src/app/models/merchant/merchant-user-list.model';

export class MerchantUsersComponent implements OnInit {
  allMerchantUserList: any[] = [];
  dataBk: IPageItem[] = this.allMerchantUserList;

  constructor(
    private merchantService: MerchantUserService
  ) {
  }

  onMerchantUserSearch() {
    this.allMerchantUserList = this.dataBk.filter(
      (row) =>
        row.merchant.userLists[0].firstName
          ?.toLowerCase()
          .includes(this.selectedName?.toLowerCase()) && row.merchant.userLists[0].lastName
          ?.toLowerCase()
          .includes(this.selectedName?.toLowerCase()) && row.merchant.userLists[0].email
          ?.toLowerCase()
          .includes(this.selectedName?.toLowerCase())
    );
  }
}

I want to filter (search) all the objects in the nested array using firstName, lastName and email in textboxes.

What I have above will only get the objects of length 0. When I did row.merchant.userLists.firstName, I got an error that firstName, lastName and email are not available in userLists.

How do I re-write onMerchantUserSearch() to achieve this?

Thanks

CodePudding user response:

1st issue

Based on your existing interface, probably you will get the error:

userLists property doesn't exist in merchant

as you miss out

userLists: IUserList[];

property in the IMerchant interface.

2nd issue

As the userLists is an array, you can't directly access the class property but you have to iterate each item in the array.

Via .find(), it will return a value if found and return null if not found. The .filter() will query the item in which the predicate (result) is neither null, undefined nor false.

this.allMerchantUserList = this.dataBk.filter((row) =>
  row.merchant.userLists.find(
    (x) =>
      x.firstName
        ?.toLowerCase()
        .includes(this.selectedName?.toLowerCase()) &&
      x.lastName
        ?.toLowerCase()
        .includes(this.selectedName?.toLowerCase()) &&
      x.email?.toLowerCase().includes(this.selectedName?.toLowerCase())
  )
);

Sample StackBlitz Demo

  • Related