Angular 8: No component factory found for the component-even added in app.module.ts - ng-modules

I am trying to migrate the project from Angular 7 to Angular 8.
However, getting the below error for the HeaderComponent after upgrading to Angular 8.
zone.js:199 Uncaught Error: No component factory found for HeaderComp. Did you add it to #NgModule.entryComponents?
at noComponentFactoryError (core.js:17988)
at CodegenComponentFactoryResolver.push../node_modules/#angular/core/fesm5/core.js.CodegenComponentFactoryResolver.resolveComponentFactory (core.js:18026)
at CodegenComponentFactoryResolver.push../node_modules/#angular/core/fesm5/core.js.CodegenComponentFactoryResolver.resolveComponentFactory (core.js:18023)
at AngularFrameworkComponentWrapper.push../node_modules/ag-grid-angular/dist/angularFrameworkComponentWrapper.js.AngularFrameworkComponentWrapper.createComponent (angularFrameworkComponentWrapper.js:65)
at DynamicAgNg2Component.createComponent (angularFrameworkComponentWrapper.js:44)
at DynamicAgNg2Component.push../node_modules/ag-grid-angular/dist/angularFrameworkComponentWrapper.js.BaseGuiComponent.init (angularFrameworkComponentWrapper.js:84)
at DynamicAgNg2Component.init (angularFrameworkComponentWrapper.js:40)
at UserComponentFactory.push../node_modules/ag-grid-community/dist/lib/components/framework/userComponentFactory.js.UserComponentFactory.initComponent (userComponentFactory.js:371)
at UserComponentFactory.push../node_modules/ag-grid-community/dist/lib/components/framework/userComponentFactory.js.UserComponentFactory.createAndInitUserComponent (userComponentFactory.js:121)
at UserComponentFactory.push../node_modules/ag-grid-community/dist/lib/components/framework/userComponentFactory.js.UserComponentFactory.newHeaderComponent (userComponentFactory.js:37)
Please find the HeaderComponent and app.module.ts below.
This is for Angular 8 so it was working in Angular 7 and after my searches on Google I improved app.module.ts by declaring entryComponent.
HeaderComponent.ts:
import { Component, OnInit, OnDestroy, Inject, forwardRef, Input } from
'#angular/core';
import { pagesToggleService } from '../../services/toggler.service'
import { Subscriber } from 'rxjs/Subscriber'
declare var pg: any;
#Component({
selector: 'pg-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
})
export class HeaderComponent implements OnInit, OnDestroy {
_headerClass = "";
isHorizontalLayout: false;
_service;
#Input()
boxed: boolean = false;
#Input()
extraClass: string = "";
constructor(private toggler: pagesToggleService) {
}
ngOnInit() {
this.isHorizontalLayout = pg.isHorizontalLayout;
this._service = this.toggler.headerClass
.subscribe(state => {
this._headerClass = state;
});
}
ngOnDestroy() {
this._service.unsubscribe()
}
}
app.module.ts:
#NgModule({
declarations: [
HeaderComponent
]
entryComponents: [
HeaderComponent
]
I expect it to work in Angular 8 but it is throwing 'No component factory found for HeaderComp.' error.
Please help me to find a solution.
Thanks,
Kind Regards.
Begum

In declaration part add first the app component in app.module.ts like :
#NgModule({
declarations: [AppComponent,HeaderComponent],
entryComponents: [HeaderComponent]
})
Thanks

The error says the HeadComp instead of HeaderComponent so it is a grid issue and I fixed it by using ngx-datatable in html.

Related

Angular 12. Inject service via forRoot into an external library, loaded from a module which has been lazy loaded by Compiler

I've created a library with a directive that injects a service. This library is loaded with a forRoot method in each lazy loaded component where is going to be used.
*** library.module ***
export const SERVICE_INYECTION_TOKEN: InjectionToken<any> = new InjectionToken('service')
export interface IDirectiveModuleConfig {
serviceAdapterConfiguration?: {provider: Provider, moduleName: string};
}
#NgModule({
imports: [
CommonModule
],
declarations: [DirectiveDirective],
exports: [DirectiveDirective]
})
export class LibraryModule {
public static forRoot(config: IDirectiveModuleConfig = {}): ModuleWithProviders<LibraryModule> {
console.log("Library loaded in module " + config.serviceAdapterConfiguration.moduleName)
return {
ngModule: LibraryModule,
providers: [
config.serviceAdapterConfiguration.provider
]
};
}
}
*** directive.directive ***
#Directive({
selector: '[directive]',
})
export class DirectiveDirective implements AfterViewInit {
#Input() methodName: string;
constructor(
private element: ElementRef,
private renderer: Renderer2,
#Inject(SERVICE_INYECTION_TOKEN) private service: any
) {}
ngAfterViewInit(): void {
this.element.nativeElement.innerText += this.service[this.methodName]()
this.renderer.setValue(this.element.nativeElement, this.service[this.methodName]())
}
}
In my main project, I have two lazy-loadeds modules, and each one have a component. One of this modules and its component are lazylodaded by the RouterModules. It works OK
*** app-routing.module ***
const routes: Routes = [
{
path: 'a',
loadChildren: () =>
import('./modules/module-a/module-a.module').then((m) => m.ModuleAModule),
},
{
path: 'b',
loadChildren: () =>
import('./modules/module-b/module-b.module').then((m) => m.ModuleBModule),
},
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
The other one is created by compileModuleAndAllComponentsAsync() and viewContainerRef.createComponent() in the parent component. It works ok without the service inection, but when I inject the service I get a NullInjectorError.
*** app.component ***
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
#ViewChild("viewContainerRef", { read: ViewContainerRef }) viewContainerRef: ViewContainerRef
component = null;
title = 'component-overview';
constructor(private compiler: Compiler, private injector: Injector) {}
async createModuleAndComponetC() {
const componentInjector: Injector = Injector.create({providers:[{provide:'service', useExisting: ServiceCService}]})
this.viewContainerRef.clear()
const module = (await import('./modules/module-c/module-c.module'))
.ModuleCModule;
this.compiler.compileModuleAndAllComponentsAsync(module).then((factory) => {
factory.ngModuleFactory.create(this.injector);
const componentFactory = factory.componentFactories[0]
const component: ComponentRef<any> = this.viewContainerRef.createComponent(componentFactory);
});
}
}
MODULE A (lazy loaded by routerModule working OK) with its component and service
const serviceConfig: IDirectiveModuleConfig = {
serviceAdapterConfiguration: {
provider: { provide: SERVICE_INYECTION_TOKEN, useClass: ServiceAService },
moduleName: 'A',
}
};
#NgModule({
imports: [
LibraryModule.forRoot(serviceConfig),
CommonModule,
ModuleARoutingModuleModule,
],
declarations: [ComponentAComponent],
exports: [ComponentAComponent],
})
export class ModuleAModule {
constructor(){
console.log("moduleA loaded")
}
}
#Component({
selector: 'app-component-a',
templateUrl: './component-a.component.html',
styleUrls: ['./component-a.component.css'],
})
export class ComponentAComponent implements OnInit {
constructor() {}
ngOnInit() {}
}
#Injectable({
providedIn: 'root'
})
export class ServiceAService {
constructor() { }
serviceA(){
return(" service A!")
}
}
MODULE C (loaded manually with compileModuleAndAllComponentsAsync() and viewContainerRef.createComponent()
export const serviceConfig: IDirectiveModuleConfig = {
serviceAdapterConfiguration: {
provider: { provide: SERVICE_INYECTION_TOKEN, useClass: ServiceCService },
moduleName: 'C',
},
};
#NgModule({
imports: [CommonModule, LibraryModule.forRoot(serviceConfig)],
declarations: [ComponentCComponent],
})
export class ModuleCModule {
constructor() {
console.log('moduleC loaded');
}
static
}
#Component({
selector: 'app-component-c',
templateUrl: './component-c.component.html',
styleUrls: ['./component-c.component.css'],
providers: [ServiceCService],
})
export class ComponentCComponent implements OnInit {
constructor() {
console.log('component C constructor');
}
ngOnInit() {
console.log('component C OnInit');
}
}
#Injectable({
providedIn: 'root',
})
export class ServiceCService {
constructor() {}
serviceC() {
return ' service C!';
}
}
In this example Modules A and B are used with router outlet, and module C is loaded with Compiler and the component is used in a *ngCompilerOutlet
I think that the problem is in the way I load my ComponentC... but I'm a little bit lost...
In adition... i've founded that the module C create a new instance each time I load this, and is not working like singleton...
stackblitz with the test project
Finally, I got success!
I saw that I could pass an injector to the viewContainerRef. CreateComponent () method. I tried with the same injector I had used to create the module in the noModuleFactory. Create () method, but it was still wrong.
Finally y realized that NgModule class exports an injector, I suposed this injector provide al the providers in this module and it works ok!!
Now my createModuleAndComponetC() is:
async createModuleAndComponetC() {
this.viewContainerRef.clear();
const module = (await import('./modules/module-c/module-c.module'))
.ModuleCModule;
this.compiler.compileModuleAndAllComponentsAsync(module).then((factory) => {
const module = factory.ngModuleFactory.create(this.injector);
const componentFactory = factory.componentFactories[0];
const component: ComponentRef<any> =
this.viewContainerRef.createComponent(
componentFactory,
0,
module.injector
);
});
}
here is the corrected stackbliz

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

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.

Angular 2 routing not working with ASP.net core MVC

i'm working in an ASP.NET Core Web Application, using Angular 2 and VS 2015 as IDE. This is totally new for me, so i've been following every tutorial to get this page work. When i finally put everything together i face a routing problem: The page stays in the loading... tag and never show the content in the ModuleViewComponent. Read a lot of stackoverflow questions but I could not fix it.
My main.ts file looks like this:
// main entry point
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
the app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { RouterModule, Routes } from '#angular/router';
import { NgForm } from '#angular/forms';
import { AppComponent } from './app.component';
import { ModuleViewComponent } from './components/CommonComponents/moduleView.component/moduleView.component';
const myRoutes: Routes = [
{
path: 'home',
component: ModuleViewComponent
},
{
path: '/',
redirectTo: 'home',
pathMatch: 'full'
}
];
#NgModule({
imports: [
RouterModule.forRoot(myRoutes),
BrowserModule,
FormsModule,
HttpModule
],
declarations: [
AppComponent,
NavbarComponent,
ModuleViewComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
template:'<router-outlet></router-outlet>'
})
export class AppComponent {
}
And the index.cshtml
#{
ViewData["Title"] = "Home Page";
}
<my-app>loading...</my-app>
How can i get this to work and show the component content? Any help is more than welcome, thanks in advance.
I have created a sample application which explains step by step details to create angular (Angular v4) applications with Asp.net MVC framework. Below is the link. Hope this helps you. You have to update route config file in your project so that angular can receive requests.
http://hive.rinoy.in/angular4-and-asp-net-mvc-hybrid-application/
http://hive.rinoy.in/routing-in-angular-asp-net-mvc-application/

Render angular2 Component on ASP.NET 5 MVC view with Routes

I am working on a ASP.NET MVC application that has several views that are serviced by a single Controller. The path of one of them is 'home/settings' and looks like this
With Angular2, I created a UserProfileComponent that basically renders a table containing list of the existing users and I would like it to render below User Profiles in the screenshot above:
user-profiles.component.ts
import { Component, Input } from '#angular/core';
import { UserService } from "../../services/userService";
#Component({
selector: 'user-profiles',
providers: [UserService],
template: `
...
`
})
export class UserProfilesComponent {
constructor(userService: UserService) {
userService.getUsers()
.subscribe(
users => this.users = users,
error => console.error('Error: ' + error),
() => console.log('Completedsfsdf!')
);
}
users = [];
}
Using Routing, I managed to render the UserProfileComponent when the settings view is rendered, but it only renders inside the tag inside the AppComponent template and I would like it to render inside my selector inside the settings view. It is also worth noting that the AppComponent is currently rendering inside the _Layout
app.ts
import { Component } from '#angular/core';
import { UserService } from './services/userService';
#Component({
selector: 'my-app',
providers: [UserService],
template: `
<p>Angular 2 is running...</p>
<!-- Routed views go here -->
<router-outlet></router-outlet>
`
})
export class AppComponent {
}
Which causes the table to render only at a layout level (on top of the page) instead on the inside the settings view.
boot.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app';
import { UserProfilesComponent } from './components/settings/user- profiles.component';
import { HomeComponent } from './components/home/home.component';
import { HttpModule } from '#angular/http';
import {UserService} from './services/userService'
import {APP_BASE_HREF} from '#angular/common';
import { RouterModule, Routes } from '#angular/router';
const appRoutes: Routes = [
{
path: 'home/settings',
component: UserProfilesComponent
},
{ path: '', component: HomeComponent }
];
#NgModule({
imports: [BrowserModule, HttpModule, RouterModule.forRoot(appRoutes)],
declarations: [AppComponent, HomeComponent, UserProfilesComponent],
providers: [{ provide: APP_BASE_HREF, useValue: '/' }],
bootstrap: [AppComponent]
})
export class AppModule { }
My initial approach here is have each section within the settings view to have its own component, so ideally RecordRollover will have its own component and so on. Is this possible?

Resources