how to call class without declaring it in constructor angular 2 - node.js

I am trying to use NFC module of Ionic 2. This is my code:
nfc-scan.ts:
import {Component} from '#angular/core';
import {IonicPage, NavController, NavParams, Platform} from 'ionic-angular';
import { Device } from '#ionic-native/device';
import {NFC, Ndef} from '#ionic-native/nfc';
#IonicPage()
#Component({
selector: 'nfc-scan',
templateUrl: 'nfc-scan.html',
})
export class NfcScan {
#ViewChild(Nav) nav: Nav;
NFC: NFC;
constructor(public platform: Platform,
public navCtrl: NavController,
public navParams: NavParams,
) {
}
// NFC Scanning
checkNFC()
{
this.NFC.enabled()
.then(() => {
this.addListenNFC();
})
.catch(err => {
console.log(err);
});
}
}
nfs-scan.html
<ion-content padding>
<button on (click)="checkNFC()">Scan NFC</button>
</ion-content>
When I run the application, I get the error:
Property 'enabled' does not exist on type 'typeof NFC'.
I know I am not declaring NFC in the constructor of nfc-scan.ts. But when I do so, the page won't even load altogether.

I did finally manage to find a solution to this problem. It turns out that it's true you can't use a class without declaring it in the constructor of the class where you want to use it.
In my case, the issue was, that I was running the app in my machine's (Macbook) browser, whereas NFC plugin can only be instantiated on a phone that supports NFC (Like camera plugin). Having said that, Ionic now provides ability to mock plugins in a way so that you can use them in your machine's browser.
To use an Ionic Native plugin in the browser and ionic serve session,
you just need to extend the original plugin class and override the
methods you’d like to mock.
Source: https://ionicframework.com/docs/native/browser.html
Hope it helps someone like me.

You would usually see an output on the console, when the page is not loading. Make sure to use private nfc : NFC in the constructor;

Related

How do you use a fallback exception filter in NestJs

I'm new to NestJs and I created a fallback exception filter, and now I would like to know how to use it. In other words, how do I import it in my application?
Here's my fallback exception filter:
#Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
public catch(exception: HttpException, host: ArgumentsHost): any {
/* Some code here */
return response.status(statusCode).json({
status: statusCode,
datetime: new Date(),
createdBy: "HttpExceptionFilter",
errorMessage: exception.message,
})
}
}
You'd need to bind the filter globally to be the fallback. You can do this one of two ways
With a custom provider in any module. Add this to the module's providers array
{
provide: APP_FILTER,
useClass: HttpExceptionFilter
}
This will still take effect in e2e tests, as it's part of the module definition
By using useGlobalFilters in your bootstrap method like so
app.useGlobalFilters(new HttpExceptionFilter());
This will not take effect in your e2e tests, so you'll need to bind it in those too, if you want the same functionality.
Just add this in your main.ts and it should work fine:
app.useGlobalFilters(new FallbackExceptionFilter();

NestJS inject custom TypeOrm repository based on an Interface

I'm currently working through the database integration docs for NestJS using TypeOrm. In these docs there are examples that show how to inject a custom database repository using the app.module from NestJS. All of these examples inject classes using the actual type of the custom repository.
#Injectable()
export class AuthorService {
constructor(private authorRepository: AuthorRepository) {}
}
This code is injected via the app.modules by providing a import like such:
#Module({
imports: [TypeOrmModule.forFeature([AuthorRepository])],
controller: [AuthorController],
providers: [AuthorService],
})
export class AuthorModule {}
This works well if you are fine with programming against an implementation, but I prefer to use an interface in my classes. I've already found the solution to injecting classes via an interface with NestJS in a previous question, but when I try to inject my custom repository like that, it doesn't seem to instanciate correctly and becomes undefined.
(node:16658) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'save' of undefined
Because of this, I assume you can only inject customRepositories via the forFeature() call in the app.module, but that won't allow me to use interfaces for injection, as far as I know. Is there any other way I can inject a custom TypeOrm repository without having the replace all my interfaces for the implementation of my custom repository? Thanks in advance!
Edit
Here is my current code, I managed to get it to inject, but this still forces me to use the implementation instead of the interface each time I call the constructor. This is mainly an issue when testing due to mocking.
#CommandHandler(FooCommand)
export class FooHandler
implements ICommandHandler<FooCommand> {
private fooRepository: IFooRepository; // Using Interface as a private property.
private barEventBus: IEventBus;
constructor(fooRepository: FooRepository,
barEventBus: EventBus) { // Forced to use implementation in constructor for injection.
this.fooRepository = fooRepository;
this.barEventBus = barEventBus;
}
#EntityRepository(FooEntity)
export class FooRepository extends Repository<FooEntity> implements IFooRepository {
getFoo() {
// Do stuff
}
}
#Module({
imports: [TypeOrmModule.forRoot(), TypeOrmModule.forFeature([FooRepository]],
// Other module setup
})
export class AppModule {}
It should work with using the InjectRepository decorator where you specify the Repository but then you type is as your interface instead and when testing you just provide the IFooRepository!
Example code:
constructor(#InjectRepository(FooRepository) fooRepository: IFooRepository,
barEventBus: EventBus) {
Edit: This answer is crap, that abstract-class-as-interface hack used does not work out as the defined methods seem to be optional to implement despite being marked as abstract.
Well, kind of got it working. Based on this answer https://stackoverflow.com/a/74561702/913136 I used an abstract class as interface (you can actually implement it) for not being required to pass strings around as tokens. Only drawback is the misuse of the abstract class. Not sure yet if I like it.
Using an actual interface in the same way seems not to be possible unfortunately. Urgh.
#Module({
imports: [
TypeOrmModule.forRoot({
...dataSource.options,
autoLoadEntities: true,
}),
TypeOrmModule.forFeature([Listing]),
],
controllers: [ViewListingController],
providers: [
{
provide: ListingRepository,
useClass: TypeOrmListingRepository,
},
],
})
makeshift interface:
import { Listing } from "./Listing";
export abstract class ListingRepository {
abstract findMostRecent: () => Promise<Listing[]>;
}
implementation:
import { Listing, ListingRepository } from "../../Domain";
import { Injectable } from "#nestjs/common";
import { Repository, DataSource } from "typeorm";
#Injectable()
export class TypeOrmListingRepository
extends Repository<Listing>
implements ListingRepository
{
constructor(private dataSource: DataSource) {
super(Listing, dataSource.createEntityManager());
}
findMostRecent() {
return this.find({});
}
}
import { Controller, Get } from "#nestjs/common";
import { ListingRepository } from "../Domain";
#Controller("listings")
export class ViewListingController {
constructor(private readonly listingRepo: ListingRepository) {}
#Get("/most-recent")
listMostRecent() {
return this.listingRepo.findMostRecent();
}
}

Highlightjs with Angular?

The ng2-smart-table application documentation has code elements snippets that look like this:
<code highlight class="typescript">{{ snippets.require }}</code>
The resulting documentation looks like this.
When looking at the resulting application html, it looks like highlightjs is doing the highlighting, but I don't see an import of an angular dependency that would perform the transform (Or any preprocessing by the scripts), so just wondering how it works?
Per the Answer
Thought is as really cool how simple this is to do with Angular:
import { Directive, ElementRef, AfterViewInit } from '#angular/core';
import * as hljs from 'highlight.js';
#Directive({
selector: 'code[highlight]',
})
export class HighlightCodeDirective implements AfterViewInit {
constructor(private elRef: ElementRef) { }
ngAfterViewInit() {
hljs.highlightBlock(this.elRef.nativeElement);
}
}
Check the code more closely there is a highlight directive (ng2-smart-table/src/app/shared/directives/highlight.directive.ts) that uses highlightjs. It is part of the sample application not the library so you need to copy it if you want to do the same in your application.

Angular 2 Material: same icon from same file displays in one component, not the other

I'm using Angular 2 rc 5 with ng2-Material alpha 7-2.
The basic problem is that using <md-icon svgIcon='icon'> to show the same icon from the same svg file will work in one component but not the other even though MdIconModule and MdIconRegistry are provided to the root AppModule
To replicate the problem
Open this plunker
Notice that MdIconModule and MdIconRegistry are imported as part of MaterialModule.forRoot() into the main AppModule
Open the AppComponent and notice the call to addSvgIconSet() to register icons
In the template, <md-icon svgIcon='ic_account_box_24px'> is used to display the icon. In the view the icon is shown successfully above the nav bar.
Open app/crisis-center/crisis.list.component and open the Crisis Center in the view.
Note in the template, the same <md-icon> is present. However, no icon is displayed above the crisis list in the view. The DOM inspector from browser dev tools shows that the angular parser didn't even recognize it as an angular component (in the dom, it's left exactly as in the code)
Because I imported the icon module and service into the root module I expected the service to be a singleton available to the whole app. Since I use that service to register the icons with iconRegistry.addSvgIconSet() in my bootstrapped AppComponent, I expected the icons to be accessible throughout the app.
PS: this may be related to what I reported yesterday, although in that case the app crashes; in this case the icon is just not shown.
import { NgModule, ModuleWithProviders } from '#angular/core';
import { MdButtonModule } from '#angular2-material/button';
import { MdCardModule } from '#angular2-material/card';
import { MdCheckboxModule } from '#angular2-material/checkbox';
import { MdCoreModule } from '#angular2-material/core';
import { MdInputModule } from '#angular2-material/input';
import { MdProgressCircleModule } from '#angular2-material/progress-circle';
import { MdToolbarModule } from '#angular2-material/toolbar';
import { MdMenuModule } from '#angular2-material/menu';
import { MdIconModule} from '#angular2-material/icon';
#NgModule({
exports: [
MdButtonModule,
MdCardModule,
MdCheckboxModule,
MdCoreModule,
MdInputModule,
MdProgressCircleModule,
MdToolbarModule,
MdMenuModule,
MdIconModule
]
})
export class MaterialModule {
static forRoot(): ModuleWithProviders {
return {
ngModule: MaterialModule,
providers: [
]
};
}
}
(this is a reproduction of my post here because the two issues are really the same)
I figured out that because MdIconModule itself has MdIconRegistry service in its providers array, every time another module imports it, a new instance of the service is provided. As a result, all components that are loaded at bootstrap time and that belong to the same AppModule share the same instance of this service. However, components loaded later (via lazy-loading) have a different instance of the service and as a result cannot see the icons registered at bootstrap time.
With help from James, I've used the workaround of a specially crafted module that does not use MdIconModule at all, but rather declares the MdIcon class alone. I then provide the MdIconRegistry service separately, and only to the root AppComponent. The result is that there is only one instance of the service app-wide and icons registered at bootstrap time are available everywhere.
Modified MdIconFixedModule
#NgModule({
imports: [CommonModule, HttpModule],
declarations: [MdIcon],
exports: [MdIcon],
providers: [],//leave empty to avoid multiple instances of MdIconRegistry
})
export class MdIconFixedModule {
static forRoot() {
return {
ngModule: MdIconFixedModule,
//will be available only to whoever calls .forRoot()
providers: [MdIconRegistry]
};
}
}
Modules that need to just use icons can import MdIconFixedModule as this doesn't contain the MdIconRegistry. The AppModule that also needs to register icons imports MdIconFixedModule.forRoot() which does contain the service.
The details of this implementation can be seen here.
This limitation of ng-Material Modules is slotted to be fixed with the alpha 8 release

Get translation text without using FormattedMessage and React ContextTypes

I'm looking for a way to get translation text without using FormattedMessage. Until now, I've found only this solution that provides to use ContextTypes an React's EXPERIMENTAL feature. Are there others ways to accomplish this (or other library/npm module)?
I prefer using context, but react-intl does also provide a higher order component injectIntl you can use instead. This will pass a prop intl that has all the imperative formatting functions.
import React from "react";
import {injectIntl, intlShape} from "react-intl";
class MyComponent extends React.Component {
static propTypes = {
intl: intlShape.isRequired
}
render() {
return <p>{this.props.intl.formatDate(new Date())}</p>;
}
}
export default injectIntl(Component);

Resources