Angular testing: Failed to load html component - html

I caught this error when testing a component with templateUrl. I don't know how to fix it.
After reading a post I added TestBed.resetTestEnvironment() and TestBed.initTestEnvironment() in the test file, but it doesn't solve the problem.
It seems like something is missing in the config file and the html file cannot be loaded.
Here are the karma logs:
Here is my karma.config.js file:
module.exports = function (config) {
config.set({
basePath: '',
frameworks: ['jasmine', 'karma-typescript'],
files: [
// Zone:
'./node_modules/zone.js/dist/zone.js', // 'Uncaught ReferenceError: Zone is not defined'
'./node_modules/zone.js/dist/proxy.js', // 'TypeError: Cannot read property 'assertPresent' of undefined'
'./node_modules/zone.js/dist/sync-test.js',
'./node_modules/zone.js/dist/async-test.js', // 'TypeError: Cannot read property 'assertPresent' of undefined'
'./node_modules/zone.js/dist/fake-async-test.js',
'./node_modules/zone.js/dist/jasmine-patch.js', // 'TypeError: Cannot read property 'assertPresent' of undefined'
// Angular:
'./node_modules/angular/angular.js',
'./node_modules/#uirouter/angularjs/release/angular-ui-router.js',
'./node_modules/angular-mocks/angular-mocks.js',
// ANY OTHER FILES TO LOAD FOR YOUR TESTS
// App:
'./assets/app/app.component.ts',
'./assets/app/app.component.html',
'./assets/app/app.component.spec.ts',
],
exclude: [
'./assets/app/main.aot.ts'
],
preprocessors: {
"**/*.ts": "karma-typescript"
},
reporters: ['spec', 'karma-typescript'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
browsers: ['Chrome'],
singleRun: false,
concurrency: Infinity,
mime: {
'text/x-typescript': ['ts', 'tsx']
}})}
In the following you can find the app.component.ts file:
import { Component } from '#angular/core';
import { Constants } from './utils/constants';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styles:[
`
#status {
background:#f8f9fa;
bottom:0;
left:0;
margin:0;
padding:0;
position:fixed;
width:100%;
}
#status div {
margin:0;
padding:5px;
text-align:center;
color:#c8c9ca;
}
`
]})
export class AppComponent {
appTitle = "App Title";
demoMode=(Constants.DEMO_MODE)?"Demo":"DefaultMode";
}
Finally, I attach the app.component.spec.ts file:
import { AppComponent } from "./app.component";
import { ComponentFixture, TestBed } from "#angular/core/testing";
import { BrowserDynamicTestingModule,
platformBrowserDynamicTesting } from '#angular/platform-browser-dynamic/testing';
import { Constants } from "./utils/constants";
describe('AppComponent', () => {
let component: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let h1: HTMLElement;
beforeEach(() => {
TestBed.resetTestEnvironment();
TestBed.initTestEnvironment(BrowserDynamicTestingModule,
platformBrowserDynamicTesting());
TestBed.configureTestingModule({
declarations: [AppComponent],
})
.compileComponents().then(()=>{
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
h1 = fixture.nativeElement.querySelector('h1');
}).catch((error)=>{
console.log(error);
});
});
it('should display original title', () => {
expect(h1.textContent).toContain("App Title");
});
it('status bar text should correspond to the working mode', () =>{
let text=(Constants.DEMO_MODE)?"Demo":"DefaultMode";
expect(document.getElementById("status-text").textContent).toEqual(text);
});
});
Thanks in advance!

You should be taking the nativeElement of the the text box as below,
h1 = fixture.nativeElement.querySelector('h1').nativeElement;
Also, please query the fixture inside the it statement and add the fixture.detectChanges(); inside the it to trigger the change detection

Related

NestJs provider isn't injected and says this.iGalleryRepository.addImage is not a function

I am trying to make a nestjs typescript backend application which uses mysql as database using clean architecture. I implemented JWT and Authorization but it doesn't see my function and i think the problem is with the dependency injection therefore i will share related files but if you need to see other files just let me know. I've been trying to solve this for 3-4 days. :/
Full Error :
ERROR Method: POST; Path: /images/add; Error: this.iGalleryRepository.addImage is not a function
My "AppModule" is named .RootModule (where i pack my app):
#Module({
imports: [
InfraModule,
AuthModule,
UserModule,
ImageModule
]
})
export class RootModule { }
Image Module:
const persistenceProviders: Provider[] = [
{
provide: DITokens.ImageDITokens.ImageRepository,
useFactory: (dataSource: DataSource) => dataSource.getRepository(TypeOrmImage).extend(TypeOrmImageRepositoryAdapter),
inject: [DITokens.CoreDITokens.DataSource]
}
];
#Module({
controllers: [
ImageController
],
providers: [
...persistenceProviders,
ImageService,
ImageHandler
]
})
export class ImageModule { }
You may ask where & how i define db (idk why 🤷‍♂️) :
export const databaseProviders = [
{
provide: DITokens.CoreDITokens.DataSource,
useFactory: async () => {
return AppDataSource.initialize();
}
}
];
.
.
.
#Global()
#Module({
imports: [
CqrsModule,
],
providers: [
...providers,
...databaseProviders
],
exports: [
DITokens.CoreDITokens.CommandBus,
DITokens.CoreDITokens.QueryBus,
DITokens.CoreDITokens.EventBus,
...databaseProviders
]
})
export class InfraModule implements OnApplicationBootstrap {
onApplicationBootstrap(): void {
initializeTransactionalContext();
}
}
Image Controller :
I should mention that Logger.log(adapter, "CreateImageDTO"); works, i can see the output but can't see the line Logger.log(createdImage, "createdImage")
#Controller('images')
#ApiTags('images')
export class ImageController {
constructor(
private readonly imageService: ImageService,
private readonly imageHandler: ImageHandler,
) { }
#Post("add")
#HttpCode(HttpStatus.OK)
#ApiBody({ type: HttpRestApiModelCreateImageBody })
#ApiResponse({ status: HttpStatus.OK, type: HttpRestApiResponseImage })
public async createImage(
#Body() body: HttpRestApiModelCreateImageBody
): Promise<CoreApiResponse<ImageUseCaseDTO>> {
const adapter: ICreateImageDTO = await CreateImageDTO.new({
parentId: body.parentId,
title: body.title,
imageUrl: body.imageUrl,
type: body.type
});
Logger.log(adapter, "CreateImageDTO")
const createdImage: ImageUseCaseDTO = await this.imageService.createImage(adapter);
Logger.log(createdImage, "createdImage")
return CoreApiResponse.success(createdImage);
}
}
Image Service
#Injectable()
export class ImageService {
/**
* #param {IGalleryRepository} iGalleryRepository
*/
constructor(
#Inject(DITokens.ImageDITokens.ImageRepository)
private readonly iGalleryRepository: IGalleryRepository
) { }
public async createImage(payload: ICreateImageDTO): Promise<ImageUseCaseDTO> {
const image: Image = await Image.new({
title: payload.title,
type: payload.type,
parentId: payload.parentId,
imageUrl: payload.imageUrl
})
await this.iGalleryRepository.addImage(image);
return ImageUseCaseDTO.newFromImage(image);
}
}
the line throws error is in the above snippet fyi
When i try to log this.iGalleryRepository using console.log() it gives the following:
Repository {
target: [class TypeOrmImage],
manager: <ref *1> EntityManager {
'#instanceof': Symbol(EntityManager),
repositories: [ [Repository], [Repository] ],
treeRepositories: [],
plainObjectToEntityTransformer: PlainObjectToNewEntityTransformer {},
connection: DataSource {
'#instanceof': Symbol(DataSource),
migrations: [],
subscribers: [],
entityMetadatas: [Array],
name: 'default',
options: [Object],
logger: [AdvancedConsoleLogger],
driver: [MysqlDriver],
manager: [Circular *1],
namingStrategy: [DefaultNamingStrategy],
metadataTableName: 'typeorm_metadata',
queryResultCache: undefined,
relationLoader: [RelationLoader],
relationIdLoader: [RelationIdLoader],
isInitialized: true
}
},
queryRunner: undefined
}
Thank you in advance.
Here we are, i solved.
dataSource.getRepository(TypeOrmImage).extend(TypeOrmImageRepositoryAdapter)
supposed to work but for some reason which i really dont know it didnt. .extend wasnt working as i expected so i would dare to say that either extend is not working properly or the way i implemented was wrong. Which means if you have this error check your implementation and if it seems right then do what i did.
I just changed
provide: DITokens.ImageDITokens.ImageRepository,
useFactory: (dataSource: DataSource) => dataSource.getRepository(TypeOrmImage).extend(TypeOrmImageRepositoryAdapter),
inject: [DITokens.CoreDITokens.DataSource]
into
provide: DITokens.ImageDITokens.ImageRepository,
useClass: TypeOrmImageRepositoryAdapter
and it indeed worked. Since i sue repository in the signiture of the class probably it generates typeorm repo.
Hope this helped!

How to prevent the user from going back to login page when hardware back button is tapped, once he's logged in in Ionc4 app?

I am developing Ionic4 App. So first I have Welcome page, that has one button "Log in" that when clicked navigates to Log In Page (using this.navCtrl.navigateRoot('/login')). When the user logs in, the Dashboard shows up using NavController in the login.ts
login() {
this.loginService.login().subscribe(user => {
this.navCtrl.navigateRoot('/dashboard');
});
}
On dashboard I register the back button in the constructor:
this.platform.backButton.subscribe( () => {
if(this.router.url=='/dashboard')
this.presentBackButtonAlert();
}
);
When the button is clicked an alert shows up to confirm if the user wants to exit the app:
presentBackButtonAlert() {
this.alertCtrl.presentAlert({
header: 'Exit?',
buttons: [
{
text: 'No',
role: 'cancel',
handler: () => {
}
}, {
text: 'Yes',
handler: () => {
console.log('Confirm Okay');
navigator['app'].exitApp();
}
}
]
});
}
The problem is when I tap the hardware back button, the alert shows up but the Dashboard Page navigates back to Welcome Page.
I expect that when I am logged in (on Dashboard Page), and tap the back button, only the alert to appear without navigating back.
Here's my AuthGuard:
import { Injectable } from '#angular/core';
import {AuthService} from '../authentication/auth.service';
import {CanActivate} from '#angular/router';
#Injectable({
providedIn: 'root'
})
export class AuthGuardService implements CanActivate{
constructor(private authService: AuthService) { }
canActivate(): boolean {
return this.authService.isAuthenticated();
}
}
And this is how I use it on the router module:
{path: 'login', loadChildren: './pages/Auth/login/login.module#LoginPageModule', pathMatch: 'full'},
{path: 'dashboard', loadChildren: './pages/company/dashboard/dashboard.module#DashboardPageModule', canActivate: [AuthGuardService]},
My authState is in the AuthService and it looks like this:
public authState = new BehaviorSubject(false);
public isAuthenticated() {
return this.authState.value;
}
The first is that simply returning the Boolean value isn't enough in a Guard. You should also tell to which page you want to go to if the condition held by the Guard isn't met
so you canActivate Method
import { Injectable } from '#angular/core';
import {AuthService} from '../authentication/auth.service';
import {CanActivate} from '#angular/router';
import { Router, ActivatedRouteSnapshot } from '#angular/router';
#Injectable({
providedIn: 'root'
})
export class AuthGuardService implements CanActivate{
constructor(private router: Router, private authService: AuthService) { }
canActivate(): boolean {
if(this.authService.isAuthenticated()){
this.router.navigate(['/whateverpage'])
return false;
}
return true;
}
}
You should also add the gaurd to the page you are about to go to. Since you want to prevent access to the login page after a user has logged in the guard should be added to the loginpage
{path: 'login', loadChildren: './pages/Auth/login/login.module#LoginPageModule' canActivate: [AuthGuardService]},
{path: 'dashboard', loadChildren: './pages/company/dashboard/dashboard.module#DashboardPageModule'},
For Ionic4, I tried this method and it is working fine for me.
Back button after login page means the user wants to exit the application or navigate to other paths.
When the view is entering I am subscribing it variable and when it leaves then unsubscribe. So that the exiting app on the back button will execute for that particular page only(e.g. dashboard page).
constructor(private platform: Platform){}
backButtonSubscription;
ionViewWillEnter() {
this.backButtonSubscription = this.platform.backButton.subscribe(async () => {
navigator['app'].exitApp();
// edit your code here
// either you exit or navigate to the desired path
});
}
}
ionViewDidLeave() {
this.backButtonSubscription.unsubscribe();
}
thanks for the question and answers, they guided me in the right way because I was facing a similar challenge, in my case, I fixed this doing something as follows on the canActivate() method on my Guard class, then I added this canActivate only to the auth page config on the app-routing.module.ts, (the rest of the pages use the canLoad instead):
canLoad(
route: Route,
segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
return this.authService.UserIsAuthenticated.pipe(
take(1),
switchMap(isAuthenticated => {
if (!isAuthenticated) {
return this.authService.autoLogin();
} else {
return of(isAuthenticated);
}
}),
tap(isAuthenticated => {
if (!isAuthenticated) {
this.router.navigateByUrl('/auth');
}
}));
}
canActivate(
route: import("#angular/router").ActivatedRouteSnapshot,
state: import("#angular/router").RouterStateSnapshot): boolean | import("#angular/router").UrlTree | Observable<boolean |
import("#angular/router").UrlTree> | Promise<boolean | import("#angular/router").UrlTree> {
return this.authService.UserIsAuthenticated.pipe(
take(1),
switchMap(isAuthenticated => {
if (!isAuthenticated) {
return this.authService.autoLogin();
} else {
return of(isAuthenticated);
}
}),
map(isAuthenticated => {
if (!isAuthenticated) {
return true;
} else {
this.router.navigateByUrl('/dashboard');
return false;
}
}));
}
So on the routing config, I only used the canActivate for the auth page...
const routes: Routes = [
{
path: '', redirectTo: 'auth', pathMatch: 'full',
canActivate: [AuthGuard]
},
{
path: 'auth',
loadChildren: () => import('./auth/auth.module').then(m => m.AuthPageModule),
canActivate: [AuthGuard]
},
{
path: 'products',
children: [
{
path: '',
loadChildren: './products/products.module#ProductsPageModule',
canLoad: [AuthGuard]
},
{
path: 'new',
loadChildren: './products/new-product/new-product.module#NewProductPageModule',
canLoad: [AuthGuard]
},
.....

Cannot read property 'builder' of undefined issue

here is my code...
custom_formio.component.ts
import { Component } from '#angular/core';
import { Router } from '#angular/router';
import { FormioAuthService } from 'angular-formio/auth';
import { Formio } from 'formiojs';
import { SelectComponent } from './Select';
#Component({
selector: 'app-custom_formio',
templateUrl: './custom_formio.component.html',
styleUrls: ['./custom_formio.component.less']
})
export class CustomFormioComponent {
builder: any;
title = 'app';
offlineCount = 0;
offlineMode: any = null;
offlineError = '';
constructor(private auth: FormioAuthService, private router: Router) {
this.auth.onLogin.subscribe(() => {
this.router.navigate(['/home']);
});
this.auth.onLogout.subscribe(() => {
this.router.navigate(['/auth/login']);
});
this.auth.onRegister.subscribe(() => {
this.router.navigate(['/home']);
});
Formio.registerComponent('custom_formio', SelectComponent);
}
}
On that SelectComponent is the my custom formio component created in Select.js that will available at https://formio.github.io/formio.js/docs/file/src/components/select/Select.js.html#lineNumber36 and to this i added some code like below..
// Use the table component edit form.
SelectComponent.editForm = TableComponent.editForm;
// Register the component to the Formio.Components registry.
Components.addComponent('custom_formio', SelectComponent);
Formio.builder(document.getElementById('builder'), {}, {
builder: {
basic: false,
advanced: false,
data: false,
layout: false,
customBasic: {
title: 'Basic Components',
default: true,
weight: 0,
components: {
select: true
}
}
}
}).then(function(builder) {
Formio.createForm(document.getElementById('formio'), {}).then(function(instance) {
var json = document.getElementById('json');
instance.on('change', function() {
json.innerHTML = '';
json.appendChild(document.createTextNode(JSON.stringify(instance.submission, null, 4)));
});
builder.on('change', function(schema) {
if (schema.components) {
instance.form = schema;
}
});
});
});
now i want to render this to html as id,for this i was created at down of above code like Formio.builder(document.getElementById('builder'), {},{}
in html i am calling this id as ...
<div id="builder"></div>
but i am getting can not read property of 'builder' undefined..
can any one suggest how to solve this....

ChildRoutes config not working anymore

So before this config use to work with react-router. But now I got a error message saying that; But I saw you need to use , but how to render the routes config insideReactDom.render( < div >
<Router history = {hashHistory}routes = {routes} > < /Router> </div>,
document.getElementById('react-app'));
?
routes.map is not a function
Can someone help me please.
const routes = {
component: Base,
childRoutes: [{
path: '/home',
getComponent: (location, callback) => {
if (Auth.isUserAuthenticated()) {
callback(null, Home);
} else {
callback(null, HomePage);
}
}
},
{
path: '/login',
component: LoginPage
},
]
}

Ensure json configuration is loaded in Angular2 [duplicate]

Is there a way to pass arguments rendered on the backend to angular2 bootstrap method? I want to set http header for all requests using BaseRequestOptions with value provided from the backend. My main.ts file looks like this:
import { bootstrap } from '#angular/platform-browser-dynamic';
import { AppComponent } from "./app.component.ts";
bootstrap(AppComponent);
I found how to pass this arguments to root component (https://stackoverflow.com/a/35553650/3455681), but i need it when I'm fireing bootstrap method... Any ideas?
edit:
webpack.config.js content:
module.exports = {
entry: {
app: "./Scripts/app/main.ts"
},
output: {
filename: "./Scripts/build/[name].js"
},
resolve: {
extensions: ["", ".ts", ".js"]
},
module: {
loaders: [
{
test: /\.ts$/,
loader: 'ts-loader'
}
]
}
};
update2
Plunker example
update AoT
To work with AoT the factory closure needs to be moved out
function loadContext(context: ContextService) {
return () => context.load();
}
#NgModule({
...
providers: [ ..., ContextService, { provide: APP_INITIALIZER, useFactory: loadContext, deps: [ContextService], multi: true } ],
See also https://github.com/angular/angular/issues/11262
update an RC.6 and 2.0.0 final example
function configServiceFactory (config: ConfigService) {
return () => config.load();
}
#NgModule({
declarations: [AppComponent],
imports: [BrowserModule,
routes,
FormsModule,
HttpModule],
providers: [AuthService,
Title,
appRoutingProviders,
ConfigService,
{ provide: APP_INITIALIZER,
useFactory: configServiceFactory
deps: [ConfigService],
multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }
If there is no need to wait for the initialization to complete, the constructor of `class AppModule {} can also be used:
class AppModule {
constructor(/*inject required dependencies */) {...}
}
hint (cyclic dependency)
For example injecting the router can cause cyclic dependencies.
To work around, inject the Injector and get the dependency by
this.myDep = injector.get(MyDependency);
instead of injecting MyDependency directly like:
#Injectable()
export class ConfigService {
private router:Router;
constructor(/*private router:Router*/ injector:Injector) {
setTimeout(() => this.router = injector.get(Router));
}
}
update
This should work the same in RC.5 but instead add the provider to providers: [...] of the root module instead of bootstrap(...)
(not tested myself yet).
update
An interesting approach to do it entirely inside Angular is explained here https://github.com/angular/angular/issues/9047#issuecomment-224075188
You can use APP_INITIALIZER which will execute a function when the
app is initialized and delay what it provides if the function returns
a promise. This means the app can be initializing without quite so
much latency and you can also use the existing services and framework
features.
As an example, suppose you have a multi-tenanted solution where the
site info relies on the domain name it's being served from. This can
be [name].letterpress.com or a custom domain which is matched on the
full hostname. We can hide the fact that this is behind a promise by
using APP_INITIALIZER.
In bootstrap:
{provide: APP_INITIALIZER, useFactory: (sites:SitesService) => () => sites.load(), deps:[SitesService, HTTP_PROVIDERS], multi: true}),
sites.service.ts:
#Injectable()
export class SitesService {
public current:Site;
constructor(private http:Http, private config:Config) { }
load():Promise<Site> {
var url:string;
var pos = location.hostname.lastIndexOf(this.config.rootDomain);
var url = (pos === -1)
? this.config.apiEndpoint + '/sites?host=' + location.hostname
: this.config.apiEndpoint + '/sites/' + location.hostname.substr(0, pos);
var promise = this.http.get(url).map(res => res.json()).toPromise();
promise.then(site => this.current = site);
return promise;
}
NOTE: config is just a custom config class. rootDomain would be
'.letterpress.com' for this example and would allow things like
aptaincodeman.letterpress.com.
Any components and other services can now have Site injected into
them and use the .current property which will be a concrete
populated object with no need to wait on any promise within the app.
This approach seemed to cut the startup latency which was otherwise
quite noticeable if you were waiting for the large Angular bundle to
load and then another http request before the bootstrap even began.
original
You can pass it using Angulars dependency injection:
var headers = ... // get the headers from the server
bootstrap(AppComponent, [{provide: 'headers', useValue: headers})]);
class SomeComponentOrService {
constructor(#Inject('headers') private headers) {}
}
or provide prepared BaseRequestOptions directly like
class MyRequestOptions extends BaseRequestOptions {
constructor (private headers) {
super();
}
}
var values = ... // get the headers from the server
var headers = new MyRequestOptions(values);
bootstrap(AppComponent, [{provide: BaseRequestOptions, useValue: headers})]);
In Angular2 final release, the APP_INITIALIZER provider can be used to achieve what you want.
I wrote a Gist with a complete example: https://gist.github.com/fernandohu/122e88c3bcd210bbe41c608c36306db9
The gist example is reading from JSON files but can be easily changed to read from a REST endpoint.
What you need, is basically:
a) Set up APP_INITIALIZER in your existent module file:
import { APP_INITIALIZER } from '#angular/core';
import { BackendRequestClass } from './backend.request';
import { HttpModule } from '#angular/http';
...
#NgModule({
imports: [
...
HttpModule
],
...
providers: [
...
...
BackendRequestClass,
{ provide: APP_INITIALIZER, useFactory: (config: BackendRequestClass) => () => config.load(), deps: [BackendRequestClass], multi: true }
],
...
});
These lines will call the load() method from BackendRequestClass class before your application is started.
Make sure you set "HttpModule" in "imports" section if you want to make http calls to the backend using angular2 built in library.
b) Create a class and name the file "backend.request.ts":
import { Inject, Injectable } from '#angular/core';
import { Http } from '#angular/http';
import { Observable } from 'rxjs/Rx';
#Injectable()
export class BackendRequestClass {
private result: Object = null;
constructor(private http: Http) {
}
public getResult() {
return this.result;
}
public load() {
return new Promise((resolve, reject) => {
this.http.get('http://address/of/your/backend/endpoint').map( res => res.json() ).catch((error: any):any => {
reject(false);
return Observable.throw(error.json().error || 'Server error');
}).subscribe( (callResult) => {
this.result = callResult;
resolve(true);
});
});
}
}
c) To read the contents of the backend call, you just need to inject the BackendRequestClass into any class of you choice and call getResult(). Example:
import { BackendRequestClass } from './backend.request';
export class AnyClass {
constructor(private backendRequest: BackendRequestClass) {
// note that BackendRequestClass is injected into a private property of AnyClass
}
anyMethod() {
this.backendRequest.getResult(); // This should return the data you want
}
}
Let me know if this solves your problem.
Instead of having your entry point calling bootstrap itself, you could create and export a function that does the work:
export function doBootstrap(data: any) {
platformBrowserDynamic([{provide: Params, useValue: new Params(data)}])
.bootstrapModule(AppModule)
.catch(err => console.error(err));
}
You could also place this function on the global object, depending on your setup (webpack/SystemJS). It also is AOT-compatible.
This has the added benefit to delay the bootstrap, whenit makes sense. For instance, when you retrieve this user data as an AJAX call after the user fills out a form. Just call the exported bootstrap function with this data.
The only way to do that is to provide these values when defining your providers:
bootstrap(AppComponent, [
provide(RequestOptions, { useFactory: () => {
return new CustomRequestOptions(/* parameters here */);
});
]);
Then you can use these parameters in your CustomRequestOptions class:
export class AppRequestOptions extends BaseRequestOptions {
constructor(parameters) {
this.parameters = parameters;
}
}
If you get these parameters from an AJAX request, you need to bootstrap asynchronously this way:
var appProviders = [ HTTP_PROVIDERS ]
var app = platform(BROWSER_PROVIDERS)
.application([BROWSER_APP_PROVIDERS, appProviders]);
var http = app.injector.get(Http);
http.get('http://.../some path').flatMap((parameters) => {
return app.bootstrap(appComponentType, [
provide(RequestOptions, { useFactory: () => {
return new CustomRequestOptions(/* parameters here */);
}})
]);
}).toPromise();
See this question:
angular2 bootstrap with data from ajax call(s)
Edit
Since you have your data in the HTML you could use the following.
You can import a function and call it with parameters.
Here is a sample of the main module that bootstraps your application:
import {bootstrap} from '...';
import {provide} from '...';
import {AppComponent} from '...';
export function main(params) {
bootstrap(AppComponent, [
provide(RequestOptions, { useFactory: () => {
return new CustomRequestOptions(params);
});
]);
}
Then you can import it from your HTML main page like this:
<script>
var params = {"token": "#User.Token", "xxx": "#User.Yyy"};
System.import('app/main').then((module) => {
module.main(params);
});
</script>
See this question: Pass Constant Values to Angular from _layout.cshtml.