The Startup
Published in

The Startup

Tech: How I Fix Strange Behavior of MatExpansionPanel

You can’t believe how easy and simple it is

I have worked with Angular Material for several years and I love how easy it is to integrate their components into my apps. Among some of the most popular components like MatTab and MatTable, I often use MatExpansionPanel to render data that regulates a parent-child relationship. The problem with MatExpansionPanel is that it will automatically close when the data is getting updated. For example, assume we have a list of parent folders which also contain several sub folders that need to be loaded at runtime. The issue occurs right after sub folder data is loaded. Since the data structure has changed MatExpansionPanel suddenly collapses and the user needs to expand the panel again to view the contents. The issue is demonstrated below:

Expansion Panel automatically closes when data get updated

My First Attempt

Initially I thought this can be easily fixed by adding some custom logic to reopen the panel after the data is getting loaded. By doing this the parent folder can finally expand after sub folders are rendered but I am not fully satisfied with the current behavior. As the result, the expansion panel starts collapsing for a few milliseconds then begins to open again which, in fact, is not very graceful to see.

Ungraceful Success

After some time struggling to find the root cause, I realized that the problem is not caused by MatExpansionPanel itself. It’s definitely a side effect of the way my data structure gets updated.

In my implementation I use *ngFor structural directives to render each expansion panel. When the data structure is updated, *ngFor destroys existing MatExpansionPanels and re-renders the components again which causes all the states of the expansion panel to be lost completely. I then started digging into Angular doc to understand how *ngFor works and found out something interesting that might help me fix this problem.

*ngFor Under The Hood

*ngFor is an Angular structural directive used to render the contents of an array of items. In each iteration, it takes the embedded template wrapped inside the directive and adds it to the DOM. When the array of items gets updated, *ngFor completely destroys the entire elements and starts inserting them back to the DOM.
Let’s circle back to my MatExpansionPanel problem. The fact that *ngFor has to rebuild everything from scratch when only the children data are changing makes it become a very expensive operation and potentially hurt the performance of the app.

*ngFor without trackBy

To mitigate this problem, *ngFor also supports an option to track down the changes and only perform DOM manipulation if necessary. The option is called trackBy. It is a function that takes two arguments: index and item. By providing this option in *ngFor, Angular will track the changes based on the return value of this function.

*ngFor with trackBy
Expansion Panel stops collapsing

Final Thought

By applying trackBy option in *ngFor, I can be able to prevent MatExpansionPanel from closing when data structure gets updated. See demo here.

Being able to understand how structural directives work in Angular helps resolve a lot of issues related to DOM rendering. If you want to learn about *ngFor, feel free to visit Angular doc for more info.

Did you see my other posts?

--

--

--

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +756K followers.

Recommended from Medium

Add & Remove TextFormFields dynamically in Flutter

Reference VS. Primitive Values

10 Days of JavaScript HackerRank Problem Solve

What Are JavaScript Bundlers?

How To Implement Client-Side Authentication in Angular

How to set up a powerful API with GraphQL, Koa, and MongoDB

how to add CORS to a dot net core web api

How to access the camera of a mobile device using React Progressive Web App (PWA)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Khoi Bui

Khoi Bui

Front End architect, opensource contributor and investment enthusiast. New content posted every week.

More from Medium

Finding an expert front-end developer

React , Angular , How to chose which one is the best for you ?

what’s my responsibility towards the web, anyway?

[Git]Front End Developer Interview Questions [Git]