Handle Recursive Inner Child Elements in Angular

Many times, we face a situation, where we need some kind of architecture that helps us achieve recursive occurrence of child elements within same child elements. For example, replies or comments of in a discussion. Each reply has same functionality and UI and there can be many replies under one reply.

First things first

Open up your 👨‍💻 terminal and run

Tip: Do not use option in actual app. We are using it here only for learning purpose. You can learn more about CLI Options here.

Great 👍. We have completed the initial setup. You’ve done a lot today. What a 🌄 day. You should take a 🛌 rest. Go 😴 nap or get a 🍲 snack. Continue once you’re 😀 awake.

Code

We will try to keep this as minimum as possible.

First, open src\app\app.component.ts and add a class property name :

and also replace the template HTML and styles with below:

The output will look like below:

Now, ideally the property should be coming from your API and you should set it in life-cycle hook.

As we discussed initially, in actual scenarios, a can have many . So, let's make change for the in our property:

Now, this won’t change anything in the output. Because we haven’t handled in our .

Let’s try something. Change HTML to below:

So, what we are doing above:

  1. We are looping through all
  2. Next, in we are checking if that reply has children
  3. If so, we are creating child list and showing the and

The output looks like below:

It worked, right? Yes, but… it’s showing just first level of children. With our current approach, we can’t cover all levels of children in each reply. Here, we need some 🤯 dynamic solution. There can be 2 ways to achieve this.

1. &

First, let’s see what is, from Angular's documentation:

The is an Angular element for rendering HTML. It is never displayed directly. In fact, before rendering the view, Angular replaces the and its contents with a comment.

Simply put, does not render anything directly whatever we write inside it. I wrote directly, so it must render indirectly, right?

We can render content of using directive in .

The Angular is a grouping element that doesn't interfere with styles or layout because Angular doesn't put it in the DOM.

Angular doesn’t render , but it renders content inside it.

Inserts an embedded view from a prepared TemplateRef.

takes an expression as input, which should return a . is nothing but given in . For example, is in below line:

We can also give some data to by setting . should be an object, the object's keys will be available for binding by the local template let declarations. Using the key in the context object will set its value as default.

See below code for example:

What’s happening in above example:

  1. We created a with as TemplateRef. This template also prints the from it's context object, thanks to .
  2. We created a . We asked it to render template with as context.
  3. We created class property, which has only one key-value pair: . Thanks to , it's value is set as default value in
  4. uses , accesses default value from and assigns it in and it prints

Okay. Let’s see how we can use all of it in our problem.

Let’s change the HTML code to below:

Almost everything is same as what was happening in previous example, but there are few additional things which are happening here. Let’s see in details:

  1. We are creating a . And we are asking it to render template with as context.
  2. Next, we are creating a with as TemplateRef. We are also using , so that inner code can use .
  3. Now, in , first we are looping through all .
  4. Then, we are checking, if any of has children.
  5. If yes, then we are repeating step 1, but with as context.

Now, the output is like below:

Cool, it renders all the levels of child replies. Now, let’s look at the second approach.

2. A Component

Instead of using and , we can also create a component to achieve same behavior.

Let’s create a component:

It will create a folder and component inside it like below:

Let’s open src\app\reply\reply.component.ts and edit it like below:

Here, we did 2 main things:

  1. We are accepting as
  2. We are looping through all the replies and printing and in >

Let’s use component in our main component:

Well, the output still reflects only 1st level of replies:

Let’s handle , too:

You noticed the change, right? We’re using again inside if that has children.

Now the output is correct, it renders all levels of replies:

The code is available at a public Github repo:

https://github.com/shhdharmen/recursive-child

Thank you,

For reading this article. Let me know your feedback and suggestions in comments sections.

And yes, always believe in yourself:

Photo by Cata on Unsplash

Originally published at https://dev.to.

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