3

I need to get configuration from server before the application bootstraps. I was able to do that using this in providers in my main ngModule:

{
    provide: APP_INITIALIZER,
    useFactory: (links: Links) => () => links.init(),
    deps: [Links, Http],
    multi: true
}

Links service:

init(): Promise<any> {
    var observable = this.http.get('someUrl').map(res => res.json());
    observable.subscribe(res => {
        this.config = res;
    });
    return observable.toPromise();
}

This code gets executed before the application bootstraps, but the response from server is not present until after my app asks for Links.config. How do I force the app to not bootstrap until after the Promise gets resolved? I tried promise.resolve(), but it didn't help.

The way I used providers I thought I forced the app to use the same instance of Links and also I thought the data would be already present there. What am I doing wrong please?

3 Answers 3

3

In my code I am doing exactly same and it's working only difference is that I am converting the request to Promise before mapping.

public load(): Promise<void> {
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let url = this.urls.settings;

    return this.http.get(url, { headers }).toPromise().
        then(configs => {
            this.startupSettings = configs.json();
        }).catch(err => {
            log(err);
        });
}

...............................

    {
        provide: APP_INITIALIZER,
        useFactory: (config: StartupConfigurationService) => () => config.load(),
        deps: [StartupConfigurationService],
        multi: true
    }

I don't sure it will make sense but try may be it will solve

Sign up to request clarification or add additional context in comments.

1 Comment

Brilliant, I had an error in resolving the promise, your way works. Thanks !
2

As suggested at #37611549 and #35215112, the @ngx-config/core utility can be helpful to get your config from server during the app initialization.

You can achieve similar results by fetching data within SystemJS imports. However, I don't suggest such an approach - because it will create a risk that your config values won't be statically analyzable during AoT compilation.

3 Comments

Just linking to your own library is not a good answer. Linking to it, explaining why it solves the problem, providing code on how to do so and disclaiming that you wrote it makes for a better answer. See: What signifies “Good” self promotion?
Thanks @Ferrybig. Of course I want to provide more detailed, in-depth code instructions. However, when I answer for the same problem on multiple threads, the system identifies it as a duplicate.
I've searched for hours about how to best provide a server-side config to the application. This answer is by far the most painless way to do it and it's very well documented. Thanks!
0

Please look at the work around that I have used here

Loading server side settings angular2 2.0.1

In short guard your route with a CanActivate class using a Promise which loads the config settings should also work.

Ensures that your settings are available when the corresponding components are constructed. (using the APP_INITIALIZER did not restrict the constructor being called, so I had to use this technic, Also please make sure, you dont export all the components in the exports:[] in the module)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.