how to include factories inside the ts file in angular 8 - angular8

I have this factory which has ngx-timpicker factory.ts , i want to include it in my ts file to use the factory in my time.ts file , but I am getting error in my import line in time.ts file that error -
TS2305: Module '"../../factories/timepickerconfig.factory"' has no exported member 'TimepickerConfig'.
7 import { TimepickerConfig } from '../../factories/timepickerconfig.factory';
~~~~~~~~~~~~~~~~
import { TimepickerConfig } from '../../factories/timepickerconfig.factory';
how to import the factories in ts file
factory/timepickerconfig.factory.ts
import { TimepickerConfig } from 'ngx-bootstrap/timepicker';
useFactory: () => {
const timepickerConfig = new TimepickerConfig();
timepickerConfig.hourStep = 2;
timepickerConfig.minuteStep = 10,
timepickerConfig.showMeridian = false,
timepickerConfig.readonlyInput = false,
timepickerConfig.mousewheel = true,
timepickerConfig.showMinutes = true,
timepickerConfig.showSeconds = false
}
time.ts
import { TimepickerConfig } from '../../factories/timepickerconfig.factory';
#Component({
selector: 'time',
templateUrl: './time.html',
styleUrls: ['./time.scss'],
encapsulation: ViewEncapsulation.None,
providers: [
{ provide: TimepickerConfig, useFactory: TimepickerConfig },
{ provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
{ provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS }]
})

Related

How to test email sending with Mailhog on local?

Setup mailhog with docker-compose like:
version: '3'
services:
mailhog:
image: mailhog/mailhog
ports:
- 8025:8025
- 1025:1025
It's possible to access localhost:8025 from browser. Maybe the SMTP server 1025 also works but don't know how to confirm it.
In a NestJS application, for testing the email code as:
#Module({
imports: [NodeMailerModule],
providers: [MailHogEmailRepository],
exports: [MailHogEmailRepository],
})
class MailHogEmailRepositoryModule {}
#Module({
imports: [MailHogEmailRepositoryModule],
providers: [
{
provide: EmailRepository,
useFactory: (
config: ConfigService,
mailHog: MailHogEmailRepository,
) => {
return mailHog;
}
},
inject: [ConfigService, MailHogEmailRepository],
},
],
exports: [EmailRepository],
})
export class EmailRepositoryModule {}
MailHogEmailRepository send with nodemailer:
#Injectable()
export class MailHogEmailRepository implements EmailRepository {
constructor(
#Inject(NodeMailerToken) private readonly nodemailer: Transporter,
) {}
async send(email: Email) {
const options = {
to: email.to,
from: email.from,
subject: email.subject,
};
await this.nodemailer.sendMail(options);
}
}
nodemailer config:
import { Module } from '#nestjs/common';
import { ConfigService } from '#nestjs/config';
import { createTransport } from 'nodemailer';
export const NodeMailerToken = Symbol('nodemailer');
#Module({
providers: [
{
provide: NodeMailerToken,
useFactory: (config: ConfigService) =>
createTransport({
host: 'localhost',
port: 1025,
secure: true,
}),
inject: [ConfigService],
},
],
exports: [NodeMailerToken],
})
export class NodeMailerModule {}
In test source, it always timeout:
import { Test, TestingModule } from '#nestjs/testing';
import request from 'supertest';
import {
FastifyAdapter,
NestFastifyApplication,
} from '#nestjs/platform-fastify';
describe('Test sender', () => {
let app: NestFastifyApplication;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication(new FastifyAdapter());
await app.init();
await app.getHttpAdapter().getInstance().ready();
});
describe('/handler (POST)', () => {
describe('should send data to mail server', () => {
it('success', () => {
const message = ...
return request(app.getHttpServer())
.post('/handler')
.send({ message })
.expect(200);
});
});
});
});
$ npm run test
thrown: "Exceeded timeout of xxx ms for a test.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
It seems the test case couldn't access the mailhog server running in docker container. How to set it correctly?

How can I get the tests to run normally (nest, unittestm fcm)?

I made unit test for sendFCM in push.service.spec.ts. but it's not working on the nest server.
Issue #1 : How can I normally give the return value of sendmulticast method?
Property 'success' does not exist on type 'void' below 'success' code.
```expect((await response).success).toBe(true);```
Issue #2 : I looked at many similar issue solutions, but couldn't find a solution to the below error. How can I test normally?
Nest can't resolve dependencies of the PushService (FIREBASE_ADMIN_INJECT, ?). Please make sure that the argument HttpService at index [1] is available in the RootTestModule
[Error Message]
FAIL push/push.service.spec.ts (24.852 s)
● PushService › should be defined
Nest can't resolve dependencies of the PushService (FIREBASE_ADMIN_INJECT, ?). Please make sure that the argument HttpService at index [1] is available in the RootTestModule context.
Potential solutions:
- If HttpService is a provider, is it part of the current RootTestModule?
- If HttpService is exported from a separate #Module, is that module imported within RootTestModule?
#Module({
imports: [ /* the Module containing HttpService */ ]
})
at TestingInjector.lookupComponentInParentModules (../node_modules/#nestjs/core/injector/injector.js:231:19)
at TestingInjector.resolveComponentInstance (../node_modules/#nestjs/core/injector/injector.js:184:33)
at TestingInjector.resolveComponentInstance (../node_modules/#nestjs/testing/testing-injector.js:16:45)
at resolveParam (../node_modules/#nestjs/core/injector/injector.js:106:38)
at async Promise.all (index 1)
at TestingInjector.resolveConstructorParams (../node_modules/#nestjs/core/injector/injector.js:121:27)
at TestingInjector.loadInstance (../node_modules/#nestjs/core/injector/injector.js:52:9)
at TestingInjector.loadProvider (../node_modules/#nestjs/core/injector/injector.js:74:9)
at async Promise.all (index 3)
● PushService › sendFCM › should return an array of Semesters
Nest can't resolve dependencies of the PushService (FIREBASE_ADMIN_INJECT, ?). Please make sure that the argument HttpService at index [1] is available in the RootTestModule context.
Potential solutions:
- If HttpService is a provider, is it part of the current RootTestModule?
- If HttpService is exported from a separate #Module, is that module imported within RootTestModule?
#Module({
imports: [ /* the Module containing HttpService */ ]
})
at TestingInjector.lookupComponentInParentModules (../node_modules/#nestjs/core/injector/injector.js:231:19)
at TestingInjector.resolveComponentInstance (../node_modules/#nestjs/core/injector/injector.js:184:33)
at TestingInjector.resolveComponentInstance (../node_modules/#nestjs/testing/testing-injector.js:16:45)
at resolveParam (../node_modules/#nestjs/core/injector/injector.js:106:38)
at async Promise.all (index 1)
at TestingInjector.resolveConstructorParams (../node_modules/#nestjs/core/injector/injector.js:121:27)
at TestingInjector.loadInstance (../node_modules/#nestjs/core/injector/injector.js:52:9)
at TestingInjector.loadProvider (../node_modules/#nestjs/core/injector/injector.js:74:9)
at async Promise.all (index 3)
[push.service.spec.ts]
import { Test, TestingModule } from '#nestjs/testing';
import { FirebaseAdminModule } from '#tfarras/nestjs-firebase-admin';
import { SendFcmReqDto } from './dtos/send-fcm.dto';
import { PushService } from './push.service';
import * as admin from 'firebase-admin';
describe('PushService', () => {
let service: PushService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [
FirebaseAdminModule.forRootAsync({
useFactory: () => ({
credential: admin.credential.applicationDefault()
})
}),
],
providers: [PushService],
}).compile();
service = module.get<PushService>(PushService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
describe('sendFCM', () => {
const sendFcmReqDto: SendFcmReqDto = {
notification_type: 'type_1',
subject: 'FCM Push Unit Test',
content: 'type1',
small_icon_url: '',
large_icon_url: '',
action1: '',
action2: '',
big_pic_url: '',
is_expand: 'true',
is_sicon: 'false',
is_licon: 'false'
}
it('should return an array of Semesters', async () => {
`const response = service.sendFCM(sendFcmReqDto);`
expect((await response).success).toBe(true);
})
})
});
[push.module.ts]
import { Module } from '#nestjs/common';
import { PushController } from './push.controller';
import { PushService } from './push.service';
import { HttpModule } from '#nestjs/axios';
import { FirebaseAdminModule } from '#tfarras/nestjs-firebase-admin';
import * as admin from 'firebase-admin';
#Module({
imports: [
HttpModule.register({
timeout: 5000,
maxRedirects: 5,
}),
FirebaseAdminModule.forRootAsync({
useFactory: () => ({
credential: admin.credential.applicationDefault()
})
}),
],
controllers: [PushController],
exports: [PushService],
providers: [PushService],
})
export class PushModule {}
import { Module } from '#nestjs/common';
import { PushController } from './push.controller';
import { PushService } from './push.service';
import { HttpModule } from '#nestjs/axios';
import { FirebaseAdminModule } from '#tfarras/nestjs-firebase-admin';
import * as admin from 'firebase-admin';
#Module({
imports: [
HttpModule.register({
timeout: 5000,
maxRedirects: 5,
}),
FirebaseAdminModule.forRootAsync({
useFactory: () => ({
credential: admin.credential.applicationDefault()
})
}),
],
controllers: [PushController],
exports: [PushService],
providers: [PushService],
})
export class PushModule {}
[push.controller.ts]
import { Body, Controller, Post } from '#nestjs/common';
import { PushService } from './push.service';
import { SendFcmReqDto } from './dtos/send-fcm.dto';
#Controller('firebase')
#Controller({ path: 'push', version: '10' })
export class PushController {
constructor(private pushService: PushService) {}
#Post('push')
sendFCM(#Body() fcmReq: SendFcmReqDto) {
return this.pushService.sendFCM(fcmReq);
}
}
[push.service.ts]
import {
BadRequestException,
Injectable,
Inject,
Logger,
NotImplementedException,
} from '#nestjs/common';
import { HttpService } from '#nestjs/axios';
import { resourceLimits } from 'worker_threads';
import { FIREBASE_ADMIN_INJECT, FirebaseAdminSDK } from '#tfarras/nestjs-firebase-admin';
import { SendFcmReqDto } from './dtos/send-fcm.dto';
import { User } from 'src/entities/User';
import { Repository } from 'typeorm';
import { InjectRepository } from '#nestjs/typeorm';
#Injectable()
export class PushService {
[x: string]: any;
private readonly logger = new Logger('PushService');
constructor(
#Inject(FIREBASE_ADMIN_INJECT)
private firebaseAdmin: FirebaseAdminSDK,
private readonly httpService: HttpService,
) {}
async sendFCM({
notification_type,
subject,
content,
small_icon_url,
large_icon_url,
action1,
action2,
big_pic_url,
is_expand,
is_sicon,
is_licon
}: SendFcmReqDto) {
this.logger.log('Start sendFCM()!');
const users = await this.usersRepository.find(
{select: ['fbToken']},
);
const ids: string[] = [];
users.forEach ((user) => {
ids.push(user.fbToken);
});
// const aps
const apsPayload = {
sound:'default',
contentAvailable:1,
alert:'default'
};
const dataPayload = {
noti_type: notification_type,
title: subject,
body: content,
s_icon_url: small_icon_url,
l_icon_url: large_icon_url,
act1: action1,
act2: action2,
b_pic_url: big_pic_url,
is_expand: is_expand,
is_sicon: is_sicon,
is_licon: is_licon
}
const multicast_message = {
tokens: ids,
priority:'high',
aps:apsPayload,
data:dataPayload,
};
await this.firebaseAdmin
.messaging()
.sendMulticast(multicast_message)
.then((response)=> {
this.logger.log('send_response:' + response);
return {
success: true,
result: response,
};
})
.catch((error) => {
this.logger.log('send_response:' + error);
return {
success: false,
result: error,
};
})
}
}

Vite is converting dynamic import statement to __import__ during build. Any way to I could fix this?

I am trying to use vite in one of my existing project. After long hard work I finally managed to make everything work in development mode. But, when I tried to test the app after building scripts with vite build, all dynamic imports failed for me. The issue was, all the import statements were being converted to __import__. If I manually replace __import__ with import on built bundles, then everything works. I tried removing #vitejs/plugin-legacy but, it still did not work.
Here is my vite.config.ts file
import { UserConfigFn } from 'vite';
import RubyPlugin from 'vite-plugin-ruby';
import FullReload from 'vite-plugin-full-reload';
import styleLint from '#amatlash/vite-plugin-stylelint';
import eslintPlugin from 'vite-plugin-eslint';
import legacy from '#vitejs/plugin-legacy';
import { resolve as _resolve, join } from 'path';
import * as tsconfig from './tsconfig.json';
const paths = tsconfig.compilerOptions.paths;
const defaultAlias = Object.keys(paths).reduce((acc, key) => {
// eslint-disable-next-line #typescript-eslint/ban-ts-comment
// #ts-ignore
const value = paths[key][0];
const path: string = key.replace('/*', '/');
acc.push({
find: path,
replacement: _resolve(__dirname, value.replace('/*', '/').replace('.//', './')) + '/',
});
return acc;
}, [] as any[]);
const configFn: UserConfigFn = ({ mode, command }) => {
const plugins =
mode === 'development' && command === 'serve'
? [
styleLint({
exclude: ['node_modules', 'public', 'plyr.css'],
}),
eslintPlugin({
fix: true,
exclude: ['node_modules', '**/legacy.js'],
}),
FullReload(['config/routes.rb', 'app/views/**/*']),
]
: [];
return {
plugins: [...plugins, legacy({}), RubyPlugin()],
css: {
postcss: '',
},
resolve: {
alias: [
...defaultAlias,
{
find: /~(.+)/,
replacement: join(process.cwd(), 'node_modules/$1'),
},
],
},
build: {
sourcemap: process.env.RAILS_ENV !== 'production',
polyfillDynamicImport: true,
rollupOptions: {
output: {
manualChunks: (id) => {
if (id.includes('node_modules')) {
if (id.includes('jquery')) {
return 'jquery';
}
if (
/creditcards|snabbdom-form|email-validator|format-numbe|form-serialize|phone-regex|email-regex|currency-regex|format-number|snake-case|number-format|superagent/.test(
id
)
) {
return 'formHelpers';
}
if (id.includes('chart.js')) {
return 'chartJs';
}
if (id.includes('moment')) {
return 'momentJs';
}
if (id.includes('imagesloaded')) {
return 'imagesLoaded';
}
if (id.includes('uuid')) {
return 'uuid';
}
if (id.includes('flimflam')) {
return 'flimflam';
}
if (/cropperjs|guillotine/.test(id)) {
return 'imageHelpers';
}
if (/ff-dashboard|ff-file-uploader/.test(id)) {
return 'ffDashboard';
}
return 'vendor';
}
},
},
},
},
clearScreen: false,
};
};
export default configFn;
Turns out it was because polyfillDynamicImport to true.

Angular 8 testing error Unexpected value 'DecoratorFactory' imported by the module 'DynamicTestModule'

I am trying to make Jasmine & Karma framework into the current angular application running in ver 8.2. But i am coming across this weird error inside the Karma test running window:
Failed: Unexpected value 'DecoratorFactory' imported by the module 'DynamicTestModule'. Please add a #NgModule annotation.
What is the problem?
My componenent.spec.ts looks like this:
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { HomeComponent } from './home.component';
import { NO_ERRORS_SCHEMA} from '#angular/core';
import {RouterTestingModule} from '#angular/router/testing';
import {HttpClientTestingModule} from '#angular/common/http/testing';
import { MsalService } from '#azure/msal-angular';
import { Store } from '#ngrx/store';
import { Pipe } from '#angular/core';
describe('HomeComponent', () => {
let component: HomeComponent;
let fixture: ComponentFixture<HomeComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, HttpClientTestingModule, Pipe]
,declarations: [HomeComponent]
,schemas:[NO_ERRORS_SCHEMA]
,providers: [
{provide: MsalService, useFactory: '' },
{provide: Store, useFactory: '' }
]
})
.compileComponents();
}));
it('should have header text', async(() => {
const fixture = TestBed.createComponent(HomeComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
//expect(compiled.querySelector('.header-txt').textContent).toContain('Tax');
}));
});
I found the cause :-
export class MockStore<T> {
private state: BehaviorSubject<T> = new BehaviorSubject(undefined);
setState(data: T) { this.state.next(data); }
select(selector?: any): Observable<T> {
return this.state.asObservable();
}
pipe() {}
dispatch(action: any) { }
}
========================================================================
TestBed.configureTestingModule({
{provide: Store, useFactory: 'MockStore' }
..............
The useFactory property must be some custom class name. Now i mocked the store class.

Using AlarmService Throws different Errors in angular 6 TypeScript

I'm having some problem in resolving this error. When i add the Alarmservice i always get this error.
When i checked this error in google, every one say, i have to add this in provider, If i add in provider also it is not working and i get a different error
import { Component, Input } from '#angular/core';
import { Client, BasicAuth, AlarmService } from '#c8y/client';
import { CumulocityService } from './c8y.service';
import {
Router
} from '#angular/router';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent {
#Input() name: string;
model = {
user: '',
password: '',
tenant: ''
};
error = {
shown: false,
msg: ''
};
disabled = false;
basicAuth: string = 'https://tempar.adamos.com'
currentUser: object = {};
constructor(
private cumulocity: CumulocityService,
private alarmService: AlarmService,
private route: Router
) { }
async login() {
this.disabled = true;
const client = new Client(new BasicAuth(
{
user: this.model.user,
password: this.model.password,
tenant: this.model.tenant
}),
this.basicAuth
);
sessionStorage.setItem("client", JSON.stringify(client));
client.inventory.list$().subscribe((data) => {
// request all inventory data via fetch and adds realtime if data changes
console.log(data);
});
try {
let user = await client.user.current();
debugger;
this.cumulocity.client = client;
console.log(user.data);
const alarmId: number = 63704;
const { data, res } = await this.alarmService.detail(alarmId);
console.log(data, res);
// this.route.navigate(['/dashboard']);
} catch (ex) {
this.cumulocity.client = null;
this.error.shown = true;
this.error.msg = ex.message;
} finally {
this.disabled = false;
}
}
}
core.js:1673 ERROR Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[LoginComponent -> AlarmService]:
StaticInjectorError(Platform: core)[LoginComponent -> AlarmService]:
NullInjectorError: No provider for AlarmService!
Error: StaticInjectorError(AppModule)[LoginComponent -> AlarmService]:
StaticInjectorError(Platform: core)[LoginComponent -> AlarmService]:
NullInjectorError: No provider for AlarmService!
at NullInjector.push../node_modules/#angular/core/fesm5/core.js.NullInjector.get (core.js:1062)
at resolveToken (core.js:1300)
at tryResolveToken (core.js:1244)
at StaticInjector.push../node_modules/#angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
at resolveToken (core.js:1300)
at tryResolveToken (core.js:1244)
at StaticInjector.push../node_modules/#angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
at resolveNgModuleDep (core.js:8376)
at NgModuleRef_.push../node_modules/#angular/core/fesm5/core.js.NgModuleRef_.get (core.js:9064)
at resolveDep (core.js:9429)
at NullInjector.push../node_modules/#angular/core/fesm5/core.js.NullInjector.get (core.js:1062)
at resolveToken (core.js:1300)
at tryResolveToken (core.js:1244)
at StaticInjector.push../node_modules/#angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
at resolveToken (core.js:1300)
at tryResolveToken (core.js:1244)
at StaticInjector.push../node_modules/#angular/core/fesm5/core.js.StaticInjector.get (core.js:1141)
at resolveNgModuleDep (core.js:8376)
at NgModuleRef_.push../node_modules/#angular/core/fesm5/core.js.NgModuleRef_.get (core.js:9064)
at resolveDep (core.js:9429)
at resolvePromise (zone.js:814)
at resolvePromise (zone.js:771)
at zone.js:873
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
at Object.onInvokeTask (core.js:3815)
at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
at drainMicroTaskQueue (zone.js:595)
If i add Alarmservice at the app.module.ts I get a different error, as said above
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { CumulocityService } from './login/c8y.service';
import { AlarmService } from '#c8y/client';
#NgModule({
declarations: [
AppComponent,
LoginComponent,
DashboardComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
],
providers: [ AlarmService, CumulocityService],
bootstrap: [AppComponent]
})
export class AppModule { }
ERROR
Uncaught Error: Can't resolve all parameters for AlarmService: (?, ?).
at syntaxError (compiler.js:1016)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getDependenciesMetadata (compiler.js:10917)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getTypeMetadata (compiler.js:10810)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getInjectableTypeMetadata (compiler.js:11032)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getProviderMetadata (compiler.js:11041)
at compiler.js:10979
at Array.forEach (<anonymous>)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver._getProvidersMetadata (compiler.js:10939)
at CompileMetadataResolver.push../node_modules/#angular/compiler/fesm5/compiler.js.CompileMetadataResolver.getNgModuleMetadata (compiler.js:10658)
at JitCompiler.push../node_modules/#angular/compiler/fesm5/compiler.js.JitCompiler._loadModules (compiler.js:23858)
Have you seen the stackblitz example? I guess you have because it looks like the code from there.
At the moment you cannot inject the services into angular directly. You can just write a wrapper around the client (like done in the example)
So to make your code working:
remove the AlarmService import
Request a alarm via this.client.alarm.detail(alarmId); instead of the AlarmService.
The this.client.alarm is of type AlarmService and uses the login you set via new Client(new BasicAuth([...]));.
In future, you can use #c8y/ngx-data to do proper dependency injection, but it is not released as stable and therefore I would not suggest to use it.