How to efficiently filter an array containing nested objects using TypeScript

I'm currently working with a list of menus and submenus:

[
    {
        "NUA_ID_Menu": 1,
        "TXT_Nom_Menu": "Menu 1",
        "Liste_Sous_Menus": [
            {
                "TXT_Nom_Menu": "SubMenu 1",
                "Liste_Direction_Menu": [
                    {
                        "NUA_ID_Direction": 2,
                        "TXT_Nom_Direction": "Direction A" 
                    },
                    {
                        "NUA_ID_Direction": 4,
                        "TXT_Nom_Direction": "Direction C"
                    }
                ]
            },
            {
                "TXT_Nom_Menu": "SubMenu 2",
                "Liste_Direction_Menu": [
                    {
                        "NUA_ID_Direction": 4,
                        "TXT_Nom_Direction": "Direction C"
                        
                    }
                ]
            },
            {
                "TXT_Nom_Menu": "SubMenu 3",
                "Liste_Direction_Menu": [
                    {
                        "NUA_ID_Direction": 3,
                        "TXT_Nom_Direction": "Direction B"
                    }
                ]
            }
        ]
    },
    {
        "NUA_ID_Menu": 2,
        "TXT_Nom_Menu": "Menu 2",
        "Liste_Sous_Menus": [
            {
                "TXT_Nom_Menu": "SubMenu 4",
                "Liste_Direction_Menu": [
                    {
                        "NUA_ID_Direction": 2,
                        "TXT_Nom_Direction": "Direction A"
                    },
                    {
                        "NUA_ID_Direction": 3,
                        "TXT_Nom_Direction": "Direction B"
                    }
                ]
            }
        ]
    }
]

I am interested in filtering menus that contain submenus with Direction C, for instance. The desired output would look like this:

[
    {
        "NUA_ID_Menu": 1,
        "TXT_Nom_Menu": "Menu 1",
        "Liste_Sous_Menus": [
            {
                "TXT_Nom_Menu": "SubMenu 1",
                "Liste_Direction_Menu": [
                    {
                        "NUA_ID_Direction": 2,
                        "TXT_Nom_Direction": "Direction A" 
                    },
                    {
                        "NUA_ID_Direction": 4,
                        "TXT_Nom_Direction": "Direction C"
                    }
                ]
            },
            {
                "TXT_Nom_Menu": "SubMenu 2",
                "Liste_Direction_Menu": [
                    {
                        "NUA_ID_Direction": 4,
                        "TXT_Nom_Direction": "Direction C"
                        
                    }
                ]
            }
        ]
    }
]

Alternatively, I want to filter the menus with submenus that contain an array of directions.

My attempts so far:

    this.mesMenus=res.filter(menu=>{
      return menu.Liste_Sous_Menus.filter(ssmenu=>{
        return ssmenu.Liste_Direction_Menu.filter(direction=>{
          return direction.NUA_ID_Direction==2;
        }).length>0;
      }).length>0;
    });

and also:

    this.mesMenus = res.map(function(menu) {
      menu.Liste_Sous_Menus = menu.Liste_Sous_Menus.map(function(ssmenu) {
        ssmenu.Liste_Direction_Menu.filter(function(direction) {
          return direction.NUA_ID_Direction==4;
        });
        return ssmenu;
      });
      return menu;
    });

I have successfully filtered with one child (this method works)

const submenus = [ 6];
    this.mesMenus =res.filter(d => d.Liste_Sous_Menus.every(c => submenus.includes(c.NUA_Id_Sous_Menu)));

However, I am struggling with filtering for grandchild elements. Could anyone provide assistance? Thank You!

Answer №1

It seems like there may be a slight misunderstanding in your question. In order to reduce both the menus and submenus, you should opt for a reduction method instead of a filtering one.

One approach could involve excluding empty menus and filtering the submenus based on their direction.

const directions = [4];
this.updatedMenus = res.reduce((acc, current) => {
     const filteredSubmenus = current.subMenus.filter(menu => menu.menuDirection.some(d => directions.includes(d)));
     if(filteredSubmenus.length > 0) {
         current.subMenus = filteredSubmenus;
         acc.push(current);
     }
     return acc;
}, []);

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

Achieving JSON element sorting in the most effective way

https://i.stack.imgur.com/NQbdN.png Each array contains the following information: {{ id: 39, treaty_number: "qwe", insurant_name: "222", belonging_to_the_holding_company: "test", date_start: "2016-04-15", etc }} Is there a way to sort each array in asc ...

Is there a way to halt the automatic expansion of a mat-expansion-panel upon being clicked?

I have a specific requirement for managing the opening and closing of my mat-expansion-panel. In my implementation, I want to rely solely on the panel's [expanded] input property to control its state. To achieve this, I am using NGRX as my state manag ...

How to style Angular Material Dropdowns: Trimming the Left and Right Sides using CSS

Seeking to customize Angular Material Select to resemble a basic dropdown. Even after applying the disableOptionCentering, the dropdown list options still expand from the left and right sides (refer to Current picture below). The desired look would involve ...

Combining subclasses in TypeScript

Do you need help with a tricky situation? ...

Setting null for HttpParams during the call

I am encountering an issue with HttpParams and HttpHeaders after upgrading my project from Angular 7 to Angular 8. The problem arises when I make a call to the API, as the parameters are not being added. Any assistance in resolving this matter would be gre ...

Different ways to display entries based on the level of authority

In my jHipster project, I have 4 entities: user, department, userAssignmentToDepartments (where a user may belong to several departments), and order. The questions I have are: How can I display only orders with a department_id that is included in the use ...

Can you explain the significance of the colon in this context?

Upon reviewing some SearchKit code snippets (composed with react/jsx and es2015), I came across the following line in a jsx file: const source:any = _.extend({}, result._source, result.highlight) I am curious about the purpose or significance of the colo ...

Leverage the power of the MEAN stack with Angular 2 to seamlessly retrieve data from multiple APIs

Using angular2, nodejs, expressjs, and mongodb for development. I need all APIs to fetch data and display it on an HTML page. Below is the code snippet from my .ts file. view image description here All APIs have been tested and are s ...

Tips for capturing your desktop screen within an angular 2+ application

I am in need of a solution to share my desktop screen using Angular 6. I have done some research to find the right package for this feature but have been unsuccessful so far. I came across various packages such as RecordRTC, Aperture, and screen-capture-r ...

Looking for assistance with an Angular2 post request?

I'm having an issue with a post request to obtain a token granting access to another access token. Each time I attempt to make the post request, I encounter an error stating that the access_token property is trying to read something undefined. It seem ...

What's the best way in Angular 6 to set focus on an element that's being made content editable?

I am currently utilizing the contentEditable attribute in Angular 6 to allow for editing the content of elements within an ngFor loop. Is there a way to focus on a tag element when its contentEditable attribute is set to true? <div class="tag" *ngFor= ...

Shifting focus among an array of standard <input> controls with each keystroke

When working with Angular, I encountered a situation where I have an array of arrays of numbers, as shown below: [ [1,1,1,1], [1,1,1,1] ] In my HTML file, I am using ngFor to generate input controls like this: <table> <tbody> ...

Launch the flutter application's web browser and seamlessly navigate back to the app

Currently, I am in the process of developing a mobile application with Flutter, alongside a web version using Angular and Node.js for the backend. I have found myself in need of a unique workflow that involves redirecting users to the web application duri ...

Exploring the data types of dictionary elements in TypeScript

I have a model structured like this: class Model { from: number; values: { [id: string]: number }; originalValues: { [id: string]: number }; } After that, I initialize an array of models: I am trying to compare the values with the o ...

Local variables are now being refreshed with every modification in the data stored in Cloud Firestore

Having trouble maintaining the accuracy of my local variables in sync with changes to the data in cloud firestore. Specifically, in my local variable called count_vehicle, the value represents a count based on specific conditions from the data in cloud fir ...

Oops! The type '{}' is lacking the properties listed below

interface Human { firstName: string; lastName: string; } let human1: Human = {}; human1.firstName = "John" human1.lastName = "Doe" Upon declaring human1, an error pops up: Type '{}' is missing the following properties from type Human ...

Applying background color within an *ngFor loop

My question may not be perfectly described by the title, but here it is. In my Angular Material2 project, I have an md-toolbar where I am dynamically looping through values: <md-toolbar (click)="selectedToolbarValue(key.Name)" *ngFor="let key of array ...

I'm currently facing a hurdle with this error, even though I've diligently followed all the necessary steps to deploy my Angular app on Her

An error occurred: Unable to access property 'Minus' of undefined. For more details, please refer to "/tmp/ng-9JMDN2/angular-errors.log". npm encountered the following errors while attempting to run scripts: ELIFECYCLE spawn file sh errno ENOENT ...

What is the best way to correctly link each object from a for loop to its corresponding DOM element?

I'm looking for a solution that resembles the following code snippet: <select> <option [bound]="items[i]" *ngFor="let item of items; #i = index">{{item}}</option> </select> ...

Utilize Angular 2 with Google Maps Places Autocomplete to dynamically update an input field with location suggestions [DOM manipulation]

Recently, I have been utilizing the "Angular 2 + Google Maps Places Autocomplete" search functionality. Essentially, it involves an input field that looks like this: <input placeholder="search your location" autocorrect="off" autocapitalize="off" spell ...