Implement cascading Dropdown fields with Angular Formly

Share this video with your friends

Social Share Links

Send Tweet

Every serious form in large apps has some dependent fields. For instance a dropdown field containing all nations and another dropdown field displaying the cities based on the currently selected nation. In this less we're looking into how we can dynamically load and filer our city dropdown based on the changes on our nation dropdown field.

Juri Strumpflohner: [0:00] Now assume our model here has another property, city ID. For now, let's also use the ID 1. Let's also go to our data service and create a new get cities method, similar to our get nations. Just like in this case, we also want to be able to give it a nation ID and filter that cities based on that nation ID.

[0:25] The nation ID will be of type number. Let's say by default, it's null. Again, we will return here an observable of type of. For now, we can remove here actual [inaudible] and that safety is null.

[0:42] As you can see, we have a similar array structure as we have for the nations, so we have always a value in the label. The only difference is that we also have a nation ID, which then allows us to filter that array based on the nation ID which we have maybe passed as a parameter.

[1:00] Again, this is just for the purpose of this demo application. In real-world scenario, this will probably be a service cycle where you pass along the nation ID, the server will down-filter the database based on that nation ID and return a new set of cities.

[1:15] Let's go back to our app component. Let's here, for now, copy our nation ID and create a new dropdown field that now maps to the city ID. Here, we would have to get cities for now. You can now see we have here Italy, which is the nations, and also the different kind of cities.

[1:39] In a real-world scenario, the cities might be a long list of cities, so definitely, we want to filter them based on our nation. Here, let's correct this label. Whenever someone changes basically that nation, we want to filter that cities dropdown field based on the value that has been chosen up here.

[2:01] One possibility to do so is to actually not directly create here that observable, but rather let's place here an empty array and use the so-called lifecycle hooks, which you have seen before. We want to use the own unit. We get here a Formly field config.

[2:19] Inside there, we can now get access to the form, which is now an angle reactive form. Therefore, what we can do here is we can get hold of that nation ID property. That nation ID points to the form control created by this Formly form conflict. This points to the underlying reactive form control.

[2:39] We can use the value changes stream here and go and register that and manipulate it. What we want to do now, specific case is want to use here a switch map. Let's quickly import that from RxJS operators. With that switch map, what we get here is the nation ID value. We want then to pass that along to our data service, which returns an observable again, and give that to the nation ID.

[3:12] As a result, from that switch map, we now get back basically the observable of cities. Those cities we want to actually associate to our template options to that, basically, empty array right now. We can directly go to the field.templateOptions.options and associate the result to that one.

[3:35] Now what you can see is that if I click here to Germany, for instance, and I map the cities, I just see German cities. If I go to Italy, I just see Italian cities. Now there's one caveat we have to still fix. If we refresh, initially, we don't see any value.

[3:53] That's because we have to use here to start with operator from RxJS and pass in our model's initial value. That will be the district model at nation ID. We also need to import that from RxJS operators. Now let's save again you can see now that correctly our city gets prefilled.