Issue with Angular library (UMD) and dynamic loading - angular7

I have an Angular app that contains a load button. When you click the load button it renders a remote UMD library.
The first time I click the load button I have the following error while importing my library using SystemJS:
core.js:15714 ERROR Error: Uncaught (in promise): TypeError: Cannot read property '__source' of undefined
TypeError: Cannot read property '__source' of undefined
at StaticInjector.push../node_modules/#angular/core/fesm5/core.js.StaticInjector.get (core.js:8984)
when I click a second time, no errors and the library renders correctly.
I narrowed the issue to this statement in my code:
export class PostService {
constructor(private httpClient: HttpClient) { }
If I remove the httpClient service, the library loads correctly but I don't have access to the HttpClient.
If anyone has an idea why my code behaves that way it would be greatly appreciated!
Here is my setup below:
I have the following components im my remote library:
sample-pack-lib.component
|_db2-chart2.component
|_post.service
The library 'samplePack-lib' is compiled with 'ng build samplePack-lib' and I exposed the following output through an express server:
dist/sample-pack-lib/sample-pack-lib.umd.js
db2-chart2.component.ts:
import { Component, ElementRef, ViewChild, AfterViewInit, OnInit } from '#angular/core';
import * as vis from 'vis';
import { Graph2d, PointItem } from 'vis';
import { PostService } from '../services/post.service';
#Component({
selector: 'izoa-db2-chart2',
templateUrl: './db2-chart2.component.html',
styleUrls: ['./db2-chart2.component.scss']
})
export class Db2Chart2Component implements OnInit {
#ViewChild('vizchart') vizchart: ElementRef;
data: Row[] = [];
constructor(private postService: PostService) { }
post.service.ts:
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class PostService {
constructor(private httpClient: HttpClient) { }
sample-pack-lib.module.ts:
import { NgModule } from '#angular/core';
import { SamplePackLibComponent } from './sample-pack-lib.component';
import { Db2Chart2Component } from './db2-chart2/db2-chart2.component';
import { Db2Chart1Component } from './db2-chart1/db2-chart1.component';
// import { HttpClientModule } from '#angular/common/http';
import {
MatButtonModule,
MatCardModule,
MatMenuModule,
MatToolbarModule,
MatIconModule,
MatSidenavModule,
MatGridListModule,
MatListModule
} from '#angular/material';
#NgModule({
declarations: [
Db2Chart2Component,
SamplePackLibComponent,
Db2Chart1Component
],
imports: [
// HttpClientModule,
MatButtonModule,
MatMenuModule,
MatCardModule,
MatToolbarModule,
MatIconModule,
MatSidenavModule,
MatGridListModule,
MatListModule
],
exports: [
SamplePackLibComponent,
Db2Chart2Component,
Db2Chart1Component
]
})
export class SamplePackLibModule { }
public-api.ts
import { NgModule } from '#angular/core';
import { SamplePackLibComponent } from './sample-pack-lib.component';
import { Db2Chart2Component } from './db2-chart2/db2-chart2.component';
import { Db2Chart1Component } from './db2-chart1/db2-chart1.component';
// import { PostService } from './services/post.service';
// import { HttpClientModule } from '#angular/common/http';
import {
MatButtonModule,
MatCardModule,
MatMenuModule,
MatToolbarModule,
MatIconModule,
MatSidenavModule,
MatGridListModule,
MatListModule
} from '#angular/material';
#NgModule({
declarations: [
Db2Chart2Component,
SamplePackLibComponent,
Db2Chart1Component
],
// providers: [PostService],
imports: [
// HttpClientModule,
MatButtonModule,
MatMenuModule,
MatCardModule,
MatToolbarModule,
MatIconModule,
MatSidenavModule,
MatGridListModule,
MatListModule
],
exports: [
SamplePackLibComponent,
Db2Chart2Component,
Db2Chart1Component
]
})
export class SamplePackLibModule { }
package.json:
{
"name": "sample-pack-lib",
"version": "0.0.1",
"dependencies": {
},
"peerDependencies": {
"#angular/common": "^7.2.0",
"#angular/core": "^7.2.0",
"#angular/material": "7.3.0"
}
}
The main app:
#Component({
selector: 'app-admin',
template: '<button (click)="load()">Load</button><ng-container #vc></ng-container>',
styleUrls: ['./admin.component.scss']
})
export class AdminComponent {
#ViewChild('vc', { read: ViewContainerRef }) vc: ViewContainerRef;
private cfr: any;
constructor(public compiler: Compiler, private injector: Injector, private r: ComponentFactoryResolver) { }
load() {
// register the modules that we already loaded so that no HTTP request is made
// in my case, the modules are already available in my bundle (bundled by webpack)
SystemJS.set('#angular/core', SystemJS.newModule(AngularCore));
SystemJS.set('#angular/common', SystemJS.newModule(AngularCommon));
SystemJS.set('#angular/material',SystemJS.newModule(AngularMaterial));
SystemJS.set('#angular/router', SystemJS.newModule(AngularRouter));
SystemJS.set('vis', SystemJS.newModule(Vis));
SystemJS.set('#angular/common/http', SystemJS.newModule(HttpClientModule));
const url = '../bundles/sample-pack-lib.umd.js';
SystemJS.import(url).then((module) => {
this.compiler.compileModuleAndAllComponentsAsync(module['SamplePackLibModule'])
.then((moduleFactory) => {
const moduleRef = moduleFactory.ngModuleFactory.create(this.injector);
const factory = moduleFactory.componentFactories.find(
item => item.componentType.name === 'SamplePackLibComponent');
if (factory) {
const component = this.vc.createComponent(factory);
const instance = component.instance;
}
});
});

The problem was with the HttpCLientModule.
Previously I imported it that way:
import { HttpClientModule } from '#angular/common/http';
It should be:
import * as HttpClientModule from '#angular/common/http';

Related

Some Angular material modules are not working in angular 10

app.module.ts
Here MatToolbarModule is not working.
The error is
File 'h:/Chale/Angular Projects/CertiStore/node_modules/#angular/material/toolbar/index.d.ts' is not a module.ts(2306)
MatListModule is not working.
The error is
Module '"../../node_modules/#angular/material/list"' has no exported member 'MatListModule'.ts(2305)
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { MatToolbarModule} from '#angular/material/toolbar';
import { MatListModule } from '#angular/material/list';
#NgModule({
declarations: [
AppComponent,
StudentDashboardComponent,
UploadComponent,
NavBarComponent
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatToolbarModule,
MatListModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
How can I get rid of these errors???
Is it because of the newest version in angular or is their anything I missed?

this.bottomSheet.open is not a function when i try open a BottomSheet with Angular Material in ionic

I have the following code based on the angular material documentation:
In my HTML
<button mat-raised-button (click)="openBottomSheet()">Abrir BottomSheet</button>
and, in my page ts archive :
import { Component, OnInit } from '#angular/core';
import {MatBottomSheet, MatBottomSheetRef} from '#angular/material/bottom-sheet';
#Component({
selector: 'app-login',
templateUrl: './login.page.html',
styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {
constructor(private bottomSheet: MatBottomSheet) {}
openBottomSheet ()
{
this.bottomSheet.open(BottomSheetOverviewExampleSheet)
}
ngOnInit() {
}
}
#Component({
selector: 'bottom-sheet-overview-example-sheet',
templateUrl: 'bottom-sheet-overview-example-sheet.html',
})
export class BottomSheetOverviewExampleSheet {
constructor(private bottomSheetRef: MatBottomSheetRef<BottomSheetOverviewExampleSheet>) {}
openLink(event: MouseEvent): void {
this.bottomSheetRef.dismiss();
event.preventDefault();
}
}
The problem is that when trying to show the bottomsheet I get the following error:
ERROR TypeError: this.bottomSheet.open is not a function
at LoginPage.openBottomSheet
In my page component i have :
import { LoginPageRoutingModule } from './login-routing.module';
import { LoginPage } from './login.page';
import { MaterialModule } from '../material.module';
import {MatBottomSheetModule} from '#angular/material/bottom-sheet'
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
LoginPageRoutingModule,
MaterialModule,
MatBottomSheetModule
],
declarations: [LoginPage]
})
export class LoginPageModule {}
The material Module
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import {
MatTableModule,
MatStepperModule,
MatButtonModule,
MatFormFieldModule,
MatInputModule,
MatOptionModule,
MatSelectModule,
MatIconModule,
MatPaginatorModule,
MatSortModule
} from "#angular/material";
import { MatCheckboxModule } from '#angular/material/checkbox';
import {MatBottomSheetRef, MatBottomSheet} from '#angular/material/bottom-sheet';
#NgModule({
declarations: [],
providers: [
{ provide: MatBottomSheetRef, useValue: {} },
{ provide: MatBottomSheet, useValue: {} },
],
imports: [
CommonModule,
],
exports: [
MatTableModule,
MatStepperModule,
MatButtonModule,
MatFormFieldModule,
MatInputModule,
MatIconModule,
MatOptionModule,
MatSelectModule,
MatPaginatorModule,
MatSortModule,
MatCheckboxModule
]
})
export class MaterialModule { }
You must import the material design module that holds this function.
Make sure you have import {MatBottomSheetModule} from '#angular/material/bottom-sheet';
imported in your component module or app module.
Update:
Instead of
import {
MatTableModule,
MatStepperModule,
MatButtonModule,
MatFormFieldModule,
MatInputModule,
MatOptionModule,
MatSelectModule,
MatIconModule,
MatPaginatorModule,
MatSortModule
} from "#angular/material";
try this,
import {MatBottomSheetRef, MatBottomSheet, MatBottomSheetModule} from '#angular/material/bottom-sheet';
import {MatCheckboxModule} from "#angular/material/checkbox";
import {MatFormFieldModule} from "#angular/material/form-field";
import {MatOptionModule} from "#angular/material/core";
import {MatSortModule} from "#angular/material/sort";
import {MatTableModule} from "#angular/material/table";
import {MatSelectModule} from "#angular/material/select";
import {MatIconModule} from "#angular/material/icon";
import {MatPaginatorModule} from "#angular/material/paginator";
import {MatStepperModule} from "#angular/material/stepper";
import {MatInputModule} from "#angular/material/input";
import {MatButtonModule} from "#angular/material/button";
in MaterialModule
Make sure you have following things.
1). in your login-page.module.ts file, "BottomSheetOverviewExampleSheet" in declarations and entryComponents
like this,
import { LoginPageRoutingModule } from './login-routing.module';
import { LoginPage, BottomSheetOverviewExampleSheet } from './login.page';
import { MaterialModule } from '../material.module';
import { MatBottomSheetModule } from '#angular/material/bottom-sheet';
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
LoginPageRoutingModule,
MaterialModule,
MatBottomSheetModule
],
declarations: [LoginPage, BottomSheetOverviewExampleSheet],
entryComponents: [BottomSheetOverviewExampleSheet],
})
export class LoginPageModule {}
2). hope you have bottom-sheet-overview-example-sheet.html
like this,
<mat-nav-list>
<a mat-list-item (click)="openLink($event)">
<span mat-line>
<!--Your message To Show -->
Test Message
</span>
</a>
</mat-nav-list>

getting error `Property 'initializeData' does not exist on type of AppConfig` on `useFactory`

I am fetching data from service on APP_INITIALIZER, but getting error as
Property 'initializeData' does not exist on type of AppConfig
don't know what is the exact issue here. any one help me?
here is my module file:
import { AppConfig } from "./shared-components/auth/AdalService";
import { AppComponent } from './app.component';
import { RoutesModule } from './routes/routes.module';
import { SignInComponent } from './shared-components/user/sign-in/sign-in.component';
export function initializeApp() {
return () => AppConfig.initializeData(); //getting error here
}
#NgModule({
declarations: [
AppComponent,
SignInComponent
],
imports: [
BrowserModule,
AngularFontAwesomeModule,
MsAdalAngular6Module,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient]
},
isolate: true
}),
SharedModule,
HttpClientModule,
iboCalendarModule,
RoutesModule,
// HttpClientInMemoryWebApiModule.forRoot(EventData),
StoreModule.forRoot({}),
EffectsModule.forRoot([]),
StoreDevtoolsModule.instrument({
name:'IBO App',
maxAge:25
})
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: initializeApp,
multi: true,
deps: [AppConfig, SignInComponent ]
},
MsAdalAngular6Service,
{
provide: 'adalConfig',
useFactory: getAdalConfig,
deps: []
},
{
provide: HTTP_INTERCEPTORS,
useClass: InsertAuthTokenInterceptor,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
Here is my service.ts:
import { Injectable, OnInit } from '#angular/core';
import { ShareOption } from "./../user/sign-in/sign-in.component";
import { Store, select } from '#ngrx/store';
import { StateShared } from "./../models/models";
#Injectable({
providedIn: 'root'
})
export class AppConfig {
constructor(){}
initializeData() {
return new Promise((resolve, reject) => resolve(true));
}
}
I bought the service in parameter, got issue fixed. my updated chunk is:
export function initializeApp(service:AppConfig) { //getting service object in param
return () => service.initializeData();
}

NullInjectorError: No provider for HttpClient! Angular 5

I, am using the Angular template in visual studio 2017. Then I updated to angular 5.2. I, tried to find the solution. But didn't got exact solution.
The service class is calling the http call.However I, am getting an error as
Service.TS
import { Injectable } from '#angular/core';
import { LoginViewModel as loginVM } from "../../viewmodel/app.viewmodel"
import { HttpClient, HttpHeaders } from "#angular/common/http";
#Injectable()
export class LoginService {
private loginUrl = "Account/Authentication";
private _httpClientModule: HttpClient;
constructor(httpClientModule: HttpClient) {
this._httpClientModule = httpClientModule;
}
public LoginHttpCall(_loginVM: loginVM) {
const headers = new HttpHeaders().set('Content-Type', 'application/json; charset=utf-8');
this._httpClientModule.post(this.loginUrl, _loginVM, { headers }).
subscribe(data => {
console.log(data);
},
err => {
console.log("Error occured.");
});
}
}
Here is my Component class
import { Component } from '#angular/core';
import { AppComponent } from "../app/app.component";
import { LoginService } from "../../service/account/app.service.account.login";
import { LoginViewModel } from "../../viewmodel/app.viewmodel";
declare var componentHandler: any;
#Component({
selector: 'login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
providers: [LoginViewModel, LoginService]
})
export class LoginComponent {
private _appComponent: AppComponent;
private _loginService: LoginService;
constructor(private appComponent: AppComponent, loginService: LoginService) {
this._appComponent = appComponent;
this._appComponent.menulist = false;
this._loginService = loginService;
}
}
app.shared.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { RouterModule } from '#angular/router';
import { AppComponent } from './components/app/app.component';
import { HomeComponent } from './components/home/home.component';
import { LoginComponent } from './components/login/login.component';
import { MobileComponent } from './components/mobile/mobile.component';
#NgModule({
declarations: [
AppComponent,
HomeComponent,
LoginComponent,
MobileComponent
],
imports: [
CommonModule,
HttpModule,
FormsModule,
RouterModule.forRoot([
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'login', component: LoginComponent },
{ path: 'mobile', component: MobileComponent },
{ path: '**', redirectTo: 'home' }
])
]
})
export class AppModuleShared {
}
I, don't know where I, am doing mistake. Since I , am new in angular. I tried to add HttpClient under #NgModule but gives some other error . Since As per my knowledge I don't need to add in app.shared.module.ts file. Since HttpClient is used in service and component level.
Can anyone please tell me where I, am doing wrong .
HttpClient needs for the module HttpClientModule instead of HttpModule to be imported and added in the imports of the module.
For more see Documentation
import { HttpClientModule } from '#angular/common/http';
#NgModule({
declarations: [
...
],
imports: [
...
HttpClientModule,
...
]
})
export class AppModuleShared { }
npm clear cache
npm update
rm -rf /node_modules
npm i --save
Then import same module into app root module.
Hope it works for you.

No provider for Http! - Angular 4 + Rails 5 API

I have followed this tutorial, and am having trouble getting it going.
I am using Angular 4.2.4.
[Error] ERROR
Error: No provider for Http!
injectionError — core.es5.js:1169
...
View_AppComponent_Host_0 (AppComponent_Host.ngfactory.js:4)
...
As I understand it, a few things have changed with Angular since this tutorial was written, including the replacement of this:
import { Http } from '#angular/http';
with this:
import { HttpModule } from '#angular/http';
I have tried this and added HttpModule to the imports array in `app.module.ts.
app.component.ts
import { Component } from '#angular/core';
import { HttpModule } from '#angular/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
books;
constructor(private http: Http) {
http.get('http://localhost:3000/books.json')
.subscribe(res => this.books = res.json());
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Any suggestions would be much appreciated.
Thanks!
You should import the Http provider from #angular/http inside your AppComponent, and add the HttpModule to the imports array of your AppModule:
AppComponent
import { Component } from '#angular/core';
import { Http } from '#angular/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
books;
constructor(private http: Http) {
http.get('http://localhost:3000/books.json')
.subscribe(res => this.books = res.json());
}
}
AppModule
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Resources