Angular 6 Error... calendar.component has no exported member 'CalendarComponent' - node.js

I report here a issue, hoping some pious souls could help..
Here's the problem, Node gives me this ERROR:
ERROR in src/app/app.module.ts(11,10): error TS2305: Module
'"V:/Projects/Kompany/source/kompany-war/src/main/websrc/test2/test-kompany/src/app/components/calendar/calendar.component"'
has no exported member 'CalendarComponent'.
src/app/components/calendar/calendar.component.ts(27,3): error TS2390:
Constructor implementation is missing.
src/app/components/oculus/oculus.component.ts(2,34): error TS2307:
Cannot find module 'components/calendar/calendar.component'.
src/app/components/top-menu/top-menu.component.ts(2,10): error TS2305:
Module
'"V:/Projects/Kompany/source/kompany-war/src/main/websrc/test2/test-kompany/src/app/components/calendar/calendar.component"'
has no exported member 'CalendarComponent'.
Here's the sitauation..
I have this on the app module...
`import { BrowserModule } from '#angular/platform-browser';`
`import { NgModule } from '#angular/core';`
`import { CalendarModule, DateAdapter } from 'angular-calendar';`
`import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';`
import { CalendarComponent } from'./components/calendar/calendar.component';
What I'm trying to do is putting a calendar library into my site.
The error is on a component I created ( Calendar Component ) and on which I put all the information I found on the web in order to try it..
https://mattlewis92.github.io/angular-calendar/docs/index.html
this is where I downloaded the library.
I'm new to Angular so I'm giving all the info I have, hope not to be boring.
Into Calender Component here is what's there...
import { Component, ChangeDetectionStrategy, OnInit } from '#angular/core';
import { CalendarEvent } from 'angular-calendar';
#Component({
selector: 'app-calendar',
changeDetection: ChangeDetectionStrategy.OnPush,
templateUrl: './calendar.component.html'
})
export class DemoComponent {
view: string = 'month';
viewDate: Date = new Date();
events: CalendarEvent[] = [
{
title: 'Click me',
start: new Date()
},
{
title: 'Or click me',
start: new Date()
}
];
constructor ()
ngOnInit() {
}
eventClicked({ event }: { event: CalendarEvent }): void {
console.log('Event clicked', event);
}
}
I read on the site that this error is due to Angular's infrastructure as I got..
And some answers to similar topics where about ordering the imports, but they are already in order.
I really don't know what to do.. hope someone will be helpful..
Lots of smiles

I see a number of errors, all of which angular is complaining about.
There is no exported class called 'CalendarComponent' in the file
you listed - in that file you export a class called 'DemoComponent'
instead.
In line 27 of your component.ts file you have no definition for the
constructor. You have constructor () but you should have
constructor() {} if you want it to be empty.
It looks like you are also attempting to import the wrongly named
class in two other components, named 'oculus.component.ts', and
'top-menu.component.ts'

Related

Cannot find name 'FontFace' when using Vexflow in Angular

Im having trouble when trying to integrate VexFlow in my Angular 12 project.
First I installed the library using:
npm install vexflow
Then I created a simple component and simply used the native api example from the documentation to try out the library. Here is the component:
import {AfterViewInit, Component, ElementRef, OnInit} from '#angular/core';
import {Renderer, Stave} from "vexflow";
#Component({
selector: 'app-note-display',
templateUrl: './note-display.component.html',
styleUrls: ['./note-display.component.scss']
})
export class NoteDisplayComponent implements OnInit, AfterViewInit {
constructor(private elRef: ElementRef) { }
ngOnInit(): void {
}
ngAfterViewInit() {
const renderer = new Renderer(this.elRef.nativeElement.querySelector('#note-display'), Renderer.Backends.SVG);
// Configure the rendering context.
renderer.resize(500, 500);
const context = renderer.getContext();
// Create a stave of width 400 at position 10, 40.
const stave = new Stave(10, 40, 400);
// Add a clef and time signature.
stave.addClef('treble').addTimeSignature('4/4');
// Connect it to the rendering context and draw!
stave.setContext(context).draw();
}
}
But Im getting the following error when serving my application:
Error: node_modules/vexflow/build/types/src/font.d.ts:132:92 - error TS2304: Cannot find name 'FontFace'.
132 static loadWebFont(fontName: string, woffURL: string, includeWoff2?: boolean): Promise<FontFace>;
I tried this solution from another question, but it was not helpful in my case.
As the other solution suggest, #types/css-font-loading-module is probably what you need.
Install it with npm i -D #types/css-font-loading-module and make sure that it is included in your tsconfig.json.
It must be added to the types field, it should like similar to this:
{
"compilerOptions": {
/* other compiler options... */
"types": ["css-font-loading-module"]
}
}

Getting the metadata of the Module in NestJs

So, I came across a situation where I need to get the metadata of the Current Module, and its controllers.
ClosedModule.ts
// all imports to AModule, BModule
#Module({
imports: [
DiscoveryModule, // given by nest/core
AModule, // it has a controller AController whose base path is A/ and has 1 function for #Get a1
BModule, // it has a controller BController whose base path is B/ and has 1 function for #Get b1
],
})
export class ClosedModule implements OnModuleInit { // ---> (X)
constructor(private readonly discovery: DiscoveryService) {}
public async onModuleInit() {
const controllers = await this.discovery.getControllers({});
controllers.map(c => console.log('---->', c.name));
}
}
In above code:
DiscoveryService, DiscoveryModule imported from '#nestjs/core';
I tried getting the information using the above code. But, there are some issues:
I am getting all the controllers in the array, rather I just need
the controllers refs for the ClosedModule class i.e current class, (X).
How can I get the base path of all the controllers under a module which IMPORTED.
2.1 Other modules
2.2 Other Controllers
Thanks in advance
Happy Coding :)
You have access to a container in your module's constructor, which has all the configurations given to the imported modules.
Here
#Module({})
export class YourModules {
constructor(readonly modulesContainer: ModulesContainer) {
const modules = [...modulesContainer.values()];
for (const nestModule of modules) {
const modulePath: string = Reflect.getMetadata(MODULE_PATH, nestModule.metatype);
}
}
// ...
}
You can find a more detailed example in the nestjsx/nest-router library.

Spartacus Compiling error in new custom paragraph component

Getting below error when compiling new custom paragraph component
**
ERROR in src/app/custom-page/new-para/new-para.component.html:7:12 - error TS2769: No overload matches this call.
The last overload gave the following error.
Argument of type 'CmsComponentData' is not assignable to parameter of type 'Promise'.
Type 'CmsComponentData' is missing the following properties from type 'Promise': then, catch, [Symbol.toStringTag], finally
7 <p *ngIf="(cmsComponent | async)?.data as data" [innerHTML]="data.content">
~~~~~~~~~
src/app/custom-page/new-para/new-para.component.ts:8:16
8 templateUrl: './new-para.component.html',
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error occurs in the template of component NewParaComponent.
**
files used:
"new-para.component.ts"
import { Component, OnInit, ChangeDetectionStrategy } from '#angular/core';
import { Observable } from 'rxjs';
import { PromotionResult, CmsService, CmsParagraphComponent } from '#spartacus/core';
import { PromotionService, CmsComponentData } from '#spartacus/storefront';
#Component({
selector: 'app-new-para',
templateUrl: './new-para.component.html',
styleUrls: ['./new-para.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NewParaComponent {
cartPromotion$: Observable<PromotionResult[]> = this.promotionService.getOrderPromotionsFromCart();
cmsComponent: CmsParagraphComponent;
constructor(protected promotionService: PromotionService,
public component: CmsComponentData<CmsParagraphComponent>,
public cmsService: CmsService) { }
}
"new-para.component.html"
<p *ngIf="(cmsComponent | async) as data" [innerHTML]="data.name"></p>
"custom-page.module.ts"
ConfigModule.withConfig({
cmsComponents: {
CMSParagraphComponent: {
component: NewParaComponent,
}
}
new console error after trying both options:
core.js:6228 ERROR Error: Uncaught (in promise): NullInjectorError: R3InjectorError(AppModule)[CmsComponentData -> CmsComponentData -> CmsComponentData]:
NullInjectorError: No provider for CmsComponentData!
NullInjectorError: R3InjectorError(AppModule)[CmsComponentData -> CmsComponentData -> CmsComponentData]:
NullInjectorError: No provider for CmsComponentData!
at NullInjector.get (core.js:1085)
at R3Injector.get (core.js:16955)
at R3Injector.get (core.js:16955)
at R3Injector.get (core.js:16955)
at NgModuleRef$1.get (core.js:36329)
at Object.get (core.js:33972)
at getOrCreateInjectable (core.js:5848)
at Module.ɵɵdirectiveInject (core.js:21103)
at NodeInjectorFactory.NewParaComponent_Factory [as factory] (new-para.component.ts:12)
Thanks for posting the code snippets, that helps. Based on the error it looks like the code is missing a few bits and pieces, but I get the idea.
Here's what you should do:
Option 1
make the component constructor arguments private or protected as you don't use it in the template
Assign the data$ property from the component.data$ to the property cmsComponent. You can do this directly when creating the property or during het oninit lifecycle hook
Observe the data$ property
component$: Observable<CmsParagraphComponent> = this.component.data$;
constructor(protected component: CmsComponentData<CmsParagraphComponent>) { }
<p *ngIf="(component$ | async) as data" [innerHTML]="data.name"></p>
Option 2
Use the public service directly in the html
Bind to the data$ property of the service
constructor(public component: CmsComponentData<CmsParagraphComponent>) { }
<p *ngIf="(component.data$ | async) as data" [innerHTML]="data.name"></p>
While option 2 is shorter, I prefer option 1. It scales better, in case you need to operate on the data stream and bring other streams into the mix.

Angular 8 adding component dynamically "viewContainerRef of undefined" error

I'm learning Angular and attempting to add a component to my HTML programmatically. However, I get the following error:
ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'viewContainerRef' of undefined
The following are the key parts of code.
My Placeholder directive:
import { Directive, ViewContainerRef } from '#angular/core';
#Directive({
selector: '[appPlaceholder]'
})
export class PlaceholderDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}
Main.component.ts:
export class MainComponent implements OnInit {
#ViewChild(PlaceholderDirective, {static: false, read: ViewContainerRef}) alertHost: PlaceholderDirective;
constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
ngOnInit(): void {
this.showMyComp();
}
private showMyComp() {
const testCmpFactory = this.componentFactoryResolver.resolveComponentFactory(TestComponent);
const hostViewContainerRef = this.alertHost.viewContainerRef;
hostViewContainerRef.clear();
hostViewContainerRef.createComponent(testCmpFactory);
}
}
Main.component.html:
<ng-template appPlaceholder></ng-template>
I have narrowed the issue down to const hostViewContainerRef = this.alertHost.viewContainerRef; in MainComponent.ts. The problem is that this.alertHost is null but I have been unable to figure out why.
I know this is an old question, but I had the same issue a few days ago:
Method that uses alertHost is invoked from ngOnInit().
To make sure that the references injected by #ViewChild are present, always write initialization code using ngAfterViewInit().
In addition to invoking showMyComp from ngAfterViewIinit, I had to update #ViewChild to following:
#ViewChild(PlaceholderDirective, {static: false}) alertHost: PlaceholderDirective;
(it is possible that this part is caused by different angular version)

Splitting inversifyJS config file into multiple files

I recently bumped into a backend project using Typescript and would like to implement IoC principle with the help of Inversify.js. Following the official documentation, I have one huge file named inversify.config.ts containing all my interfaces and classes that implement them:
import "reflect-metadata"
import { Container } from "inversify"
import TYPES from './types';
import { ModuleRepo } from '../repo/interfaces'
import { ModuleARepoImpl } from '../repo/moduleA'
import { ModuleBRepoImpl } from '../repo/moduleB'
import { ModuleService } from '../services/interfaces'
import { ModuleAServiceImpl } from '../services/moduleA'
import { ModuleBServiceImpl } from '../services/moduleB'
const container = Container();
container.bind<ModuleRepo>(TYPES.ModuleARepo).to(ModuleARepoImpl);
container.bind<ModuleRepo>(TYPES.ModuleBRepo).to(ModuleBRepoImpl);
container.bind<ModuleService>(TYPES.ModuleAService).to(ModuleAServiceImpl);
container.bind<ModuleService>(TYPES.ModuleBService).to(ModuleBServiceImpl);
export default container;
One big problem in the above setting is when the project gets complex, more modules are added resulting in a very long config file (imagine you have dozens of modules). My plan is to divide it into smaller config files, with inversify.config.ts remains the main file.
consider the following settings:
./dependencies/interface/index.ts
import { Container } from 'inversify';
export type InversifyContainer = Container
export interface BasicInterface {
register(container: InversifyContainer): void
readonly types: Object
}
./dependencies/moduleA/index.ts
import {InversifyContainer, BasicDependencies} from '../interface';
import { ModuleRepo } from '../../repo/interfaces'
import { ModuleARepoImpl } from '../../repo/moduleA'
import { ModuleService } from '../../services/interfaces'
import { ModuleAServiceImpl } from '../../services/moduleA'
export class ModuleADependencies {
register(container: InversifyContainer) {
container.bind<ModuleRepo>(TYPES.ModuleARepo).to(ModuleARepoImpl);
container.bind<ModuleService>(TYPES.ModuleAService).to(ModuleAServiceImpl);
}
readonly types = {
ModuleARepo: Symbol('ModuleARepo'),
ModuleAService: Symbol('ModuleAService'),
}
}
./dependencies/inversify.config.ts
import "reflect-metadata"
import { Container } from "inversify"
import { ModuleADependencies } from './moduleA';
import { ModuleBDependencies } from './moduleB'; // consider moduleB also has the same file
const container = Container();
const registrationList = [ModuleADependencies, ModuleBDependencies];
for (const reg of registrationList) {
new reg().register(container);
}
export default container;
./dependencies/types.ts
import { ModuleADependencies } from './moduleA';
import { ModuleBDependencies } from './moduleB';
const TYPES = {
...(new ModuleADependencies().types),
...(new ModuleBDependencies().types),
}
export default TYPES
However, this way I always have an error showing something like Cannot read property of ModuleARepo of undefined from the types. I browsed the internet however nobody seems to care about how lengthy and messy inversify.config.ts would be if it is in a complex project.
Hoping someone can help with this :)
First of all your problem is described in the doc and has a solution.
Your solution is generally correct but there is a circular dependency
./dependencies/types.ts -> ./dependencies/moduleA/index.ts -> ./dependencies/types.ts
In types a new instance of class is created but the module that contain the class definition imports types. You don't list this import but use TYPES.ModuleARepo in bind.
To avoid it you can make types field static or move it out of the class into a separate exportable object. As a positive side effect of it, there will be no need to instantiate a class in ./dependencies/types.ts.
Just in case please keep in mind that if you instantiate a class that has a Symbol as a field this symbol is unique for every instance since Symbol('ModuleARepo') !== Symbol('ModuleARepo').
Playground

Resources