If anyone faces the same problems and want me to write the actual implementation please comment below.
While working on my dev.to clone in Angular I came across the comments section which can be very tricky to render. As it has a tree like structure which can go infinitely.
├── comment
│ ├── comment ─── comment
│ │ └── comment
│ ├── comment
│ ├── comment ─── comment ─── comment
│ │ └── comment ─── comment ─── comment
│ └── comment
├── comments
│ ├── comment ─── comment
│ │ └── comment
│ └── comment
├──── comment
│ ├── comment
│ └── comment
└──── comments
Rendering comments
We never know the actual structure of the comments. I looked closely at the structure and I saw its just like recursion the same component is calling the same component. So I tried that and it worked.
I passed the comments array to a component and it renders it with a ngFor after I call the same component pass to it its children and go about that again and again. You can check it out
Spacing comments
Next problem was CSS I wanted to add space before each comment when it goes to the next level but after 4 levels we need to stop adding spaces in comments other wise there will be no space for comments. Here we have one advantage aver the above problem we know the level after which we want to remove the CSS if we don't try to make it generic we can just do
.app-comments .app-comments .app-comments .app-comments {
padding-left: 0;
}
using specificity we can take advantage of us knowing the level at which to remove padding.
Toggling functionality
If we use any library managing state of such a structure can be a night mare. I used the native details html tag which comes with the toggling functionality in built and we need not manage any state this is the point where I realize how powerful these structures can be.
State problems
Working with the details tag was great but I needed the state of it closing and opening in the template. To show and hide some data whenever the state changes. To do that and not manage any state I thought of using template variables and @ViewChild
but failed miserably managing state at each level of an Array of dynamic length array was really hard which is changing its state I have to manage a tree like state for components to to mitigate this I thought lets completely keep the state in the template and I used the same template variable and use the native open property on details element to show and hide elements but nothing was happening. I really tried everything but the open property never changed in the template.
Ngzone problem
So I got to know that on open close of detail HTML element a toggle event is generated and zone.js has not monkey patched the toggle event. What a pain when you expect something to work in the frame work and it does not work and you need to have deep understanding of the frame to solve it and if if you have a good amount of knowledge you can't solve it. To resolve this I imported ChangeDetectorRef and detectChanges on when the toggle event happens.
Top comments (2)
Interesting showcase of some Angular pains 👍
Didn't you check how the nested comments are implemented in forem BTW?
No I didn't check it
It's not the showcase of angular pains only ngZone problem is angular specific rest I think will be same in all the frameworks and libraries. Maybe state is solved with react hooks but I'm not sure of it