Configure an Angular App at Runtime

It always again happens (especially in real world scenarios) that you need to configure your Angular app at runtime. That configuration might be fetched from some backend API, or it might be some simple JSON configuration sitting on your deployment server. The key here is that you want to be able to dynamically modify and adjust that configuration without the need to re-compile and re-deploy your application. Also, you most probably want that configuration to be loaded and ready once your application bootstrapping is done.
In this lesson we learn how to make use of the APP_INITIALIZER to hook into Angular's initialization process. That will allow us to inject some configuration into our app just when it is about to start up.

You must be a Member to view code

Instructor: 00:01 There are a lot of scenarios in real world applications where you actually want to configure your app at runtime based on some conditions. That could be, for instance, just to visualize the version of that application, or you could even want to configure the behavior of the application based on which client has that application where is actually deployed.

00:20 Now, one possibility is, of course, go in our app component, and download that configuration here. You basically do some HTTP requests, get that configuration, and then inject it here in our application. What you would want to do, however, is to prevent your application from running until that configuration has actually arrived.

00:39 You could actually use your NGF, and say something like config loaded, which you then basically set in your app component once the configuration's here. That would mean then the components inside here would then start up, and continuing running.

00:53 There is a better concept, however, in Angular what we can use. That is basically to use the so-called app initializer. We can import that from Angular core here, and then what we can do is to define here a provider, where we say provide the app initializer, and use a factory function, which we'll define here.

01:12 Say here, const app initializer function. That is actually a function which should return another function, which then basically our app initializer can load. We will use that function here below. We have to specify multi true so that we can actually register multiple app initializers here.

01:33 Finally, we can even provide some dependencies to our app initializer function here, which in this case, is simply empty. Now, let's write here some console log statement. When our application refreshes, you can see here how our app initializing is being printed to our console.

01:52 Now, let's make this a bit more real life, and let's here use that assets folder to create some data folder inside there. Let's say we have here our app config, which is a JSON file which we could actually deploy via our deployment pipeline dynamically.

02:09 Let's enter here some configuration. In this case, I specify the name of our app, and let's say, version number. Obviously, there could be other stuff which is relevant for your application.

02:20 Next, let's then create a specific service which will be responsible for loading our configuration. Let's call it app config service. The scaffold here will look something like this. We will need here, obviously, the HTTP client, which we can import here from the common HTTP part.

02:42 Then let's say we have a function, load app config, which actually executes that HTTP call. In our example of our Angular CLI project, we will call the assets folder, the data folder inside there, and then the app config, which we just specified.

02:58 Normally, in an HTTP call, you would then subscribe to that, and basically take that data. Let's say this.appConfiguration equals data. That will be here, private variable, appConfig, where we store actually the configuration, such that later on, we can then get that config from some other places.

03:21 Now, what's here important to note is that we cannot actually use here an observable, because in this case, basically, our load app config would return an observable. We have to use a promise. We will see immediately why that's the case.

03:35 Let's simply transform this to a promise. As a consequence, also here, we have to use the den for R then to subscribe. It's actually pretty easy to configure that.

03:43 Now, let's go back to our app module, and provider section, we will have to import here our newly created app configuration service. It obviously has to be imported at the very top here. Now, what we actually want is to inject it inside our app initializer function, so we will get this here as a dependency.

04:04 Here, we can then do appConfig.loadApplicationConfiguration. Finally, we also need to make sure that we get our dependency injected. We do that by providing it to that depth property down here.

04:17 Now, note we return here the load application config return time, which in our case, is actually here the promise. Whenever then our app initializer sees here a promise being returned, it will wait until that promise is being resolved.

04:32 We can verify that by jumping to our app component. In our app component, what we are going to do is to get the configuration service. Then the ngOnInit, we can do this.title, for instance, equals this.configService.getConfig, which is now loaded by this time. We inject here basically the name of our application.

04:54 Now, let's save this. As you can see now, we get the name that has been configured in our app config JSON file.