Issues have been identified with the collapse functionality of the Angular 6 Material Tree feature

Recently, I've been working on creating a tree structure to handle dynamic data using Angular material tree component. In order to achieve this, I referred to the code example mentioned below:

https://stackblitz.com/edit/material-tree-dynamic

However, I encountered an issue with the tree structure I developed, where the collapse functionality was not working as expected. I decided to copy the code from the above example and run it on my own machine. Here is the TypeScript file I used (the HTML code remained the same):

import {Component, Injectable} from '@angular/core';
import {FlatTreeControl} from '@angular/cdk/tree';
import {CollectionViewer, SelectionChange} from '@angular/cdk/collections';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
import {Observable} from 'rxjs/Observable';
import {merge} from 'rxjs/observable/merge';
import {map} from 'rxjs/operators/map';

// code continues...

Upon collapsing a root node that contains multiple levels of children, the resulting display can be seen here.

If anyone has insights into what might be causing this issue and how to resolve it, I would greatly appreciate the assistance.

Answer №1

Reason Behind the Behavior

The issue arises due to the implementation of the toggle function. When collapsing a node by calling toggleNode with the expand parameter set to false, the following line of code is executed:

this.data.splice(index + 1, children.length);

In the Flat Tree data structure used for the Material Tree, nodes are stored in a simple array along with their respective levels. The structure might resemble the following:

- Root (lvl: 1)
- Child1 (lvl: 2)
- Child2 (lvl: 2)
- Child1OfChild2 (lvl: 3)
- Child2OfChild2 (lvl: 3)
- Child3 (lvl: 2)

It is important to note that child elements are placed after their parent in the array when expanding a node. The issue arises when collapsing a node, especially if any of its children are expanded and have children of their own. This can be understood by revisiting the line of code mentioned previously.

Proposed Solution

To address this issue, I replaced the problematic line of code with the following logic:

const afterCollapsed: ArtifactNode[] = this.data.slice(index + 1, this.data.length);
let count = 0;
for (count; count < afterCollapsed.length; count++) {
    const tmpNode = afterCollapsed[count];
    if (tmpNode.level <= node.level){
        break;
    }
}
this.data.splice(index+1, count);

By utilizing the slice function and a for-loop, the revised logic accurately determines the number of elements to remove from the array when collapsing a node, ensuring that all appropriate child nodes are removed as well.

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

Two tags attached to four hypertext links

Within my HTML code, I have hyperlinks present on every line. However, I am seeking to eliminate these hyperlinks specifically from "your previous balance" and "your new balance".https://i.sstatic.net/ekVGT.png In the following HTML snippet: <tr *ngFor ...

What causes the session storage to be accessed across various browser sessions?

Scenario While working on an application, I discovered an intriguing behavior in Chrome 62 on Windows 10 related to defining values in sessionStorage. Surprisingly, changing a value in one tab affected other tabs that shared the same key. Initially, I b ...

Is there a way to modify the style when a different rarity is selected in Next.JS?

Is there a way to change the style depending on the rarity selected? I am currently developing a game that assigns a random rarity upon website loading, and I am looking to customize the color of each rarity. Here is how it appears at the moment: https:/ ...

Is it possible for a React selector to retrieve a particular data type?

As a newcomer to React and Typescript, I am currently exploring whether a selector can be configured to return a custom type. Below is a basic selector that returns a user of type Map<string, any>: selectors/user.ts import { createSelector } from ...

Currently trapped within the confines of a Next.js 13 application directory, grappling with the implementation of a

I need to figure out how to export a variable from one component to layout.tsx in such a way that it is not exported as a function, which is currently causing the conditional check in the class name to always be true. Below is the code snippet: // File w ...

What is the best way to separate the user interface module from the logic in Angular2?

I am diving into Angular2 for the first time and have been tasked with creating a module using UI components like @angular/material. The goal is to shield my team members from the complexities of the UI framework I choose, allowing them to focus solely on ...

Is it possible that I am making a mistake when using the multi-mixin helper, which is causing an unexpected compiler error that I cannot

As I work on creating a multi-mixin helper function that takes in a map of constructors and returns an extended map with new interfaces, I come across some challenges. Let's first look at the basic base classes: class Alpha { alpha: string = &ap ...

Divide a string using multiple delimiters just one time

Having trouble splitting a string with various delimiters just once? It can be tricky! For instance: test/date-2020-02-10Xinfo My goal is to create an array like this: [test,Date,2020-02-10,info] I've experimented with different approaches, such ...

Ionic user interface is not appearing on screen

While following a tutorial on this website, I encountered my first issue in the file todo.service.ts: An error stating "Property 'key' does not exist on type 'Todo'" was displayed. Below is the interface code for todo.ts: export inte ...

Searching function in material-table does not work properly with pipe symbol

Within my data table, I utilize the @pipe to display name instead of position in the position row... The name is sourced from a separate JSON file... <ng-container matColumnDef="position"> <mat-header-cell *matHeaderCellDef> No. </ma ...

Numerous unspecified generic arguments

Imagine a collection of functions, each capable of taking an argument and returning a value (the specifics don't matter): function convertToNumber(input: string): number { return parseInt(input) } function convertToBoolean(input: number): boolean { ...

Using TypeScript with Angular-UI Modals

Currently, my goal is to create a modal using angular-ui-bootstrap combined with typescript. To begin, I referenced an example from this link (which originally utilizes jQuery) and proceeded to convert the jQuery code into typescript classes. After succes ...

Unable to trigger click or keyup event

After successfully implementing *ngFor to display my data, I encountered an issue where nothing happens when I try to trigger an event upon a change. Below is the snippet of my HTML code: <ion-content padding class="home"> {{ searchString ...

Retrieve information and transform it into a dynamic variable using Firebase

I am trying to retrieve data from the current user, specifically their company named "ZeroMax", and then store this data in a global variable. The purpose of this variable is to define the path for Firebase. I believe my code gives a clear understanding of ...

The application is having trouble accessing the property 'isXXXXX' because it is undefined

My attempt to utilize a shared service in one of my components has been successful when used with the app's root component. However, I encountered an error when trying to implement it on another module or dashboard. https://i.sstatic.net/x3rRv.png s ...

Receiving feedback from an http.post request and transferring it to the component.ts file in an Angular

Currently, I am facing an issue with passing the response from an http.post call in my TypeScript service component to an Angular 2 component for display on the frontend. Below are the code structures of my service.ts and component.ts: getSearchProfileRes ...

Steps to link two mat-autocomplete components based on the input change of one another

After reviewing the content on the official document at https://material.angular.io/components/autocomplete/examples I have implemented Autocomplete in my code based on the example provided. However, I need additional functionality beyond simple integrati ...

Injecting services and retrieving data in Angular applications

As a newcomer to Angular, I am trying to ensure that I am following best practices in my project. Here is the scenario: Employee service: responsible for all backend calls (getEmployees, getEmployee(id), saveEmployee(employee)) Employees components: displ ...

Is there a way to obtain a unique response in TestCafe RequestMock?

With Testcafe, I have the capability to simulate the response of a request successfully. I am interested in setting up a caching system for all GET/Ajax requests. The current setup functions properly when the URL is already cached, but it fails to prov ...

Stock Chart that resembles the functionality of Google's popular line chart feature

Can anyone recommend a Javascript or SVG chart library that has a style similar to a Google Chart? I have been searching without much luck and would appreciate some guidance on how to achieve a similar look. I've looked into the Google Visualization ...