6

Error : Tried to find bootstrap code, but Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options.

main.ts

getHttp().get('/assets/config.json').toPromise()
 .then((res: Response) => {
 let conf = res.json();
 platformBrowserDynamic().bootstrapModule(createAppModule(conf));
})

I am using angular-cli. With angular v2.3.1 this code was working fine.

I want to fetch json and pass it to @Ngmodules providers

{ provide: Config, useValue: conf } 
Rohit
  • 2,987
  • 3
  • 25
  • 50
  • What are you trying to achieve ? just fetch json and pass it to ?.... – VikingCode Apr 13 '17 at 11:17
  • I want to fetch json and want to pass it @Ngmodules providers { provide: Config, useValue: conf } – Rohit Apr 13 '17 at 13:03
  • Is the JSON just an application configuration or `createAppModule()` creates different modules according to the values from the `conf` variable? Can you add that code to your question? – Ján Halaša Apr 14 '17 at 06:21

3 Answers3

3

If the data you are fetching from config.json are just about a configuration of an application module and you are trying to create a Config service to store them, I think the best would be to assign it to the environment and read it in your Config service later. The environment is available in main.ts, so no hacking (createAppModule) needed.

import { environment } from './environments/environment';
import { AppModule } from './app/';

getHttp().get('/assets/config.json').toPromise()
   .then((res: Response) => {
       let conf = res.json();
       environment.settings = conf;
       platformBrowserDynamic().bootstrapModule(AppModule);
});

You must also declare all new properties of environment in your src/environments/environment.ts file.

Ján Halaša
  • 8,167
  • 1
  • 36
  • 36
  • This doens't work if you want to use the config settings (say urls) in the configuration for imported modules. eg. `myFancyLib.forRoot({ backend: environment.backend })` :( – Yoeri Jan 25 '18 at 13:56
2

The cli is attempting to use ahead of time compilation. Because of this, it needs to be able to find your main NgModule.

Usually the AOT compiler is able to do this statically just by looking for bootstrap calls. However you are not immediately bootstrapping, so the compiler needs you to explicitly tell it the name of your app module so it can compile it and all of it's components.

Solutions

ng eject and manually configure entryModule

The preferred solution is to tell the cli the name of your entryModule. This will allow AOT to work and give you all of it's benefits. However the cli does not currently support this(But there is a PR for adding an option #4077).

The current workaround is to use ng eject --aot to switch to a manual webpack based build. Then you can configure your entryModule directly.

  1. ng eject --aot
  2. Open webpack.config.js and search for new AotPlugin
    • Add the following and replace your AppModule name
      entryModule: 'path/to/app.module#AppModule'

Skip AOT

You can entirely skip this issue by using the --no-aot flag if you just need to get a build working. This isn't recommended as your app will be much slower and larger than it normally would(it will have to compile components at runtime and you will have to ship the compilier which is large).

ng prod --no-aot

epelc
  • 5,300
  • 5
  • 22
  • 27
  • 1
    actually you can specify the entry module alrady in the `tsconfig.json`... I'm doing it for quite a time already: ` "angularCompilerOptions": { "entryModule": "app/app/app.module#AppModule" }` – OschtärEi Jul 20 '17 at 08:44
2

The accepted answer didn't work for me. Extracting the bootstrapModule part will let Angular find the bootstrap code.

import { environment } from './environments/environment';
import { AppModule } from './app/';

const bootstrap = () => {
  platformBrowserDynamic().bootstrapModule(AppModule);
};

getHttp().get('/assets/config.json').toPromise()
    .then((res: Response) => {
       let conf = res.json();
       environment.settings = conf;
       bootstrap();
});
Niels Steenbeek
  • 4,692
  • 2
  • 41
  • 50
  • My app does bootstrapping conditionally. This solved my problem and it seems logical too. Anyone opposed to this fix? Why is there no upvotes for this solution? – Miklós Kosárkár May 28 '18 at 08:47