Add Angular Material to Lib in Nx Monorepo - angular-material

I am trying to view a story of an Angular Material Button. However, in the story, the button does not have any styles. I imported angular material using : ng add angular/material and these ara my files for my component :
This is the html file :
<button mat-button color="primary">Button Material</button>
This is the module of my lib :
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RouterModule, Route } from '#angular/router';
import { ElementComponent } from './element/element.component';
import {MatButtonModule} from '#angular/material/button';
import { MaterialComponent } from './material/material.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
export const plateRoutes: Route[] = [];
#NgModule({
imports: [CommonModule, RouterModule,BrowserAnimationsModule, MatButtonModule],
declarations: [
ElementComponent,
MaterialComponent,
],
})
export class PlateModule {}
This is the component story :
As you can see the style does not apply to the mat button...

In your MaterialComponent you have to import the material module of Button
import { MatButtonModule } from '#angular/material/button';
import { Meta, moduleMetadata, Story } from '#storybook/angular';
import { ButtonComponent } from './button.component';
export default {
title: 'button',
component: ButtonComponent,
decorators: [
moduleMetadata({
imports: [MatButtonModule],
}),
],
} as Meta<ButtonComponent>;
And after this you will need to add the style in the build step of the storybook
{
...
"build-storybook": {
...
"options": {
"styles": [
// the style that you should import
"./node_modules/#angular/material/prebuilt-themes/indigo-pink.css"
]
},
}
...
}

Related

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>

Why does Angular Calendar show plain texts and numbers only?

The picture above is the only display when I added Angular Calendar. Does it have conflict with Font Awesome? Because I installed Font Awesome in my Angular project with Angular Material as its main styling and component framework.
HTML:
<mwl-calendar-month-view [viewDate]="viewDate" [events]="events">
</mwl-calendar-month-view>
TS:
import { Component } from '#angular/core';
import { CalendarEvent, CalendarUtils } from 'angular-calendar';
#Component({
selector: 'app-creator-profile-calendar',
templateUrl: './calendar.component.html',
styleUrls: ['./calendar.component.scss'],
})
export class CalendarComponent {
viewDate: Date = new Date();
events: CalendarEvent[] = [];
}
Module:
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { CalendarComponent } from './components/calendar/calendar.component';
import { CalendarModule, DateAdapter } from 'angular-calendar';
import * as moment from 'moment';
import { adapterFactory } from 'angular-calendar/date-adapters/moment';
export function momentAdapterFactory() {
return adapterFactory(moment);
};
#NgModule({
declarations: [
CalendarComponent
],
imports: [
CommonModule,
CalendarModule.forRoot({ provide: DateAdapter, useFactory: momentAdapterFactory })
],
})
export class CreatorProfileModule { }
Oh okay. I forgot to add "./node_modules/angular-calendar/css/angular-calendar.css" in angular.json
That solved this problem when you manually install.
Add in your component encapsulation: ViewEncapsulation.None
. it will work

Issue with Angular library (UMD) and dynamic loading

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';

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.

Angular2 cant bind element in angular2-infinite-scroll

I am new to angular 2 and what I did is use the angular infinite scroll and load the data when the scroll is scrolled but it prompt some error cannot bind property I illustrated below error :
install angular 2-infinite-scroll
import { NgModule, enableProdMode, CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { HttpModule } from '#angular/http';
import { FormsModule } from '#angular/forms';
import { Routes } from '#angular/router';
import { AppComponent } from './app/app.component';
/* Feature Modules */
import { DatepickerModule } from 'ng2-bootstrap/ng2-bootstrap';
import { PlanModule } from './plan.module';
import { InfiniteScrollModule } from 'angular2-infinite-scroll';
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
enableProdMode();
#NgModule({
imports: [
BrowserModule,
HttpModule,
FormsModule,
DatepickerModule.forRoot(),
PlanModule,
InfiniteScrollModule
],
declarations: [],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }
platformBrowserDynamic().bootstrapModule(AppModule);
add html page
<div id="activityList" *ngIf="structure.jobplan" infinite-scroll
[infiniteScrollDistance]="2"
[infiniteScrollThrottle]="300"
(scrolled)="bindActivitiesOnScroll($event)" >
then i got error :
Uncaught Error: Template parse errors:
Can't bind to 'infiniteScrollDistance' since it isn't a known property of 'div'. ("
<div id="activityList" *ngIf="structure.jobplan" infinite-scroll
[ERROR ->][infiniteScrollDistance]="2"
[infiniteScrollThrottle]="300"
(scrolled)="bindAct"): ng:///ActivityModule/ActivityListComponent.html#5:12
Can't bind to 'infiniteScrollThrottle' since it isn't a known property of 'div'. ("t" *ngIf="structure.jobplan" infinite-scroll
[infiniteScrollDistance]="2"
[ERROR ->][infiniteScrollThrottle]="300"
(scrolled)="bindActivitiesOnScroll($event)" >
"): ng:///ActivityModule/ActivityListComponent.html#6:12
at syntaxError (index.ts:26)
at TemplateParser.parse (index.ts:26)
at JitCompiler._compileTemplate (index.ts:26)
at index.ts:26
at Set.forEach (<anonymous>)
at JitCompiler._compileComponents (index.ts:26)
at index.ts:26
at Object.then (index.ts:26)
at JitCompiler._compileModuleAndComponents (index.ts:26)
at JitCompiler.compileModuleAsync (index.ts:26)
i googled but cant find a solution why it does not allowing to bind property,
couldn't find where i made mistake please help me
what i did was to import
import { InfiniteScrollModule } from 'angular2-infinite-scroll';
inside my app.module.ts

Resources