Occasionally, a use case arises where an Angular component must be able to recursively enumerate some data structure. A few simple examples include:
- Render a family tree in an application which tracks family histories.
- Render a directory structure in a file browsing application.
- Enumerate the properties of an arbitrary JSON object.
- Visually render a sitemap.
One way to fulfill this requirement is to make an Angular component whos HTML markup references itself. This approach is very similar to normal recursion with functions. In the sections below we will give a brief refresher on recursion in this context, then outline the steps for creating the recursive component.
Recursion with Components
An angular component is recursive if it references its own tag within its own template HTML. Recursion with Angular components is almost identical to recursion with functions; it must adhere to the normal princples of recursion
- There must be at least one reachable base case. The recursion must end at some point, otherwise the program will eventually run out of memory. Common base cases include ending when some array is empty, when some child is null, some child list is empty, or some value is 0.
- There must be at least one reachable recursive call. The template must have a reachable branch where it invokes itself. Furthermore, it must pass in different data than it received itself, otherwise an infinite loop will occur (this isn't necessarily true if global state comes into play but such circumstances should be avoided).
Creating the Component
For this example we are going to create a component which recursively enumerates a directory and its children. It will list the name of each directory, the names of the files in it, and for each child directory, do the same. Each nested level will appear farther to the right to make it easier for the user to visualize the nested structure. To implement this component, we will:
- Define a type definition for the directory structure.
For this demo, each directory will include a name property, list of fileNames property, and list of child directories property. This definition will be recursive itself, so the list of child directories will be a list of the same type as this type itself. This results in a tree structure. - Create the component ts file.
We will create a simple component ts file and set the selector name to "file-dir-view". - Add an input property for the directory structure.
In the component ts, we will add an "@Input" property which will accept a single directory item. We could alternatively accept a list of directory items but will not do so in this example. - Create the HTML markup.
The component will display the current directory's name, list of files, and its child directories. For the first two parts, we can use standard logic to display those details. For the last part, we will make our recursive call. - Make the recursive call in the HTML markup.
For each child directory within the current directory, we will render a new "file-dir-view" component. Note that as a result, "file-dir-view" components will have other "file-dir-view" child components. - Add recursive styling.
Within the component's css, we will add a rule to add a left margin to "file-dir-view" components. As a result, each nested component will be more indented than the last.
The code example below puts the steps above into practice. The last tab Rendered Result renders the code using an example input.
Recursive Sitemap Parsing
This recursive component approach is used on this website to recursively render our website's sitemap.xml contents. For a detailed explanation of its implementation, please visit the dev page below: