Replace Angular Structural Directives with Control Flow Syntax using Angular Migrations

Tomasz Ducin
InstructorTomasz Ducin
Share this video with your friends

Social Share Links

Send Tweet

Use automatic migration to make your angular codebase use the new control flow. Or follow a manual step-by-step migration, if needed.

The new control flow syntax in Angular, available from version 17, simplifies template syntax and eliminates the need to import CommonModule.

To adopt the new syntax, Angular developers can either manually update their templates using the @if, @for, and @switch blocks or utilize the official migration schematic provided by the Angular CLI.

The schematic (ng generate @angular/core:control-flow) automatically migrates existing code to utilize the new control flow syntax. This new syntax offers improved readability and maintainability for Angular templates.

Additionally, by removing the requirement to import CommonModule, the new control flow syntax can lead to a slight reduction in bundle size.

[00:00] Modern Angular has introduced the new control flow syntax, which allows us to replace the old Angular structural directive such as the ng if, ng for, ng switch, and so on and so forth with their new substitutes, which is the if block, the far block, and so on and so forth. As you can see, they're quite [00:19] similar. So why would one replace them at all? First and foremost, the reason is performance. The Angular directives are being executed in runtime, which in a big amount could take a quite significant amount of time. Whereas, the syntax blocks are pre compiled by the [00:39] compiler so that the components output file already includes just the minimum amount of the runtime JavaScript code that is going to be executed. All in all, they are faster and it's worth to do the replacement. So let's start with doing it manually. So that would be the if. Here we just need to put the [00:59] semicolon. And what we just need to do is basically to put the entire div inside this one here so that we can see everything is okay. Just this else loading is going to be removed. And what is nice, this NG template with the template variable [01:18] loading, we don't need all of this because there is an else one. And what we can do is basically do that like this. As you can see, the manual migration is quite tedious, and there is quite a lot of manual work that we would do. So let's run the automatic Angular migration. [01:39] We're going to run ng generate, and that is angular/core. And here goes the control flow. The only thing that we need to have is Angular core, so there are no additional dependencies required. So the first question is, which path in your project should [01:59] be migrated? So just as an example, we can run this on the src/app/employees just to show that we can do the migration incrementally, not just on the entire project. And there is a question, should the migration reformat your template? So that's basically formatting of our [02:18] templates. Let's run this. So we can see that there have been 2 files that have been updated. So I'm going to rerun this migration just on the entire application. So the default is to run it on pretty much everything, and we will see that there would be a little bit more of these files. So let's analyze them and we'll get back to [02:38] this error later. So one of the file that we're going to take a look is the benefit listing component HTML file. So what we can see here is that we've got the if statement. We also have the for statement being migrated over here. What is important in the older version of [02:58] the n g if, the track by part was not required. However, in the new for block, the track part is required. And since in the previous code, Angular didn't have it, but now it needs to provide something over here, most often, what is going to [03:18] happen is Angular is going to track the object reference, which is certainly not we want to have here. So if this is an object that especially includes the ID or any kind of ID equivalent, this is something that we might need to do manually because there is basically no way for Angular to figure out that this [03:38] is the property that we might want to track. Another thing that we might want to add manually is the empty block, which is going to be executed when the sequence that we're going to iterate over is simply empty. So what we can put here is basically no items found or whatever [03:58] is basically the label. And Angular is not capable of migrating this since there was no equivalent built in into the ng four directive. So even though Angular automates quite a lot of this work, the semantics have slightly changed. So for this [04:17] reason, it's a good idea to apply the migration partially, so that we can take care of these things, such as the track empty, etcetera, manually. Now we can go further into this warning over here. So it says that the template that I've got here encountered one error, which says that the [04:37] text note service benefit the service cannot be put within the NG switch part. So this line is the source of the error. And it used to be correct before, but now it's not. So what we need to do in this case is basically to get this line over here [04:57] outside of the NG switch. We're going to save this file. And we'll basically run the migration again, and we'll see that this file is going to be migrated correctly. And we can see that here we've got NG switch migrated to switch, the case, and default that we can see over here. And let's also take a [05:17] look at the diff over here. So the NG switch, NG switch case, switch default, etcetera, everything is migrated. Let's also see that everything works correctly inside our application. Last thing to note, we might want to remove unnecessary imports from our components. [05:36] So before the migration, we've been using the directive such as the NG switch, ng f, ng 4. And right now, after the migration, we are using the new control flow syntax, which is pre compiled. There are no directives, so we might not need to import the common module. Now we might have been importing [05:56] the common module either into the NG module or into the standalone components. So let's take a look here at an example benefit listing component, t s, which is an example, standard load component and which also imports the common module. So it could happen that we could basically remove [06:16] the common module import entirely. Let's see if this is our case. It seems not. Because if we take a look at the components listing HTML, we will see that the async pipe is still required. However, it's not required for us to import the entire common module, [06:36] but we can just import only the thing that we actually need. So still, the entire common module is not required.