Ionic4: Phonegap-nfc: where is the content? - ionic4

VERSION: Ionic 4
Plugin: phonegap-nfc
Hi everyone!
I'm trying to use this plugin (https://ionicframework.com/docs/native/nfc) and following the instructions, I should be able to read a message sent from another NFC device. The event is fired and I know something is sent, but I'm not able to understand what and where the message is stored.
This is the code:
home.page.ts
import { Component } from '#angular/core';
import {Ndef, NFC} from '#ionic-native/nfc/ngx';
import {AlertController} from '#ionic/angular';
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor(private nfc: NFC, private ndef: Ndef, private alertController: AlertController) { }
readNFC() {
this.nfc.addNdefListener(() => {
this.presentAlert('ok');
}, (err) => {
this.presentAlert('ko' + err);
}).subscribe((event) => {
console.log(event);
console.log(JSON.stringify(event));
this.presentAlert('Il messaggio contiene' + event.tag + ' ' + this.nfc.bytesToHexString(event.tag.id));
});
}
writeNFC() {
this.nfc.addNdefListener(() => {
console.log('successfully attached ndef listener');
const message = this.ndef.textRecord('Hello world');
this.nfc.share([message]).then(
value => {
this.presentAlert('ok');
}
).catch(
reason => {
this.presentAlert('ko');
}
);
}, (err) => {
this.presentAlert('ko' + err);
});
}
async presentAlert(mess) {
const alert = await this.alertController.create({
header: 'attenzione',
message: mess,
buttons: ['OK']
});
await alert.present();
}
}
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import {Ndef, NFC} from '#ionic-native/nfc/ngx';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
NFC,
Ndef
],
bootstrap: [AppComponent]
})
export class AppModule {}
This is the stringify obtained by printing the content of event:
{"isTrusted":false,"tag":{"id":[0],"techTypes":["android.nfc.tech.Ndef"],"type":"android.ndef.unknown","maxSize":0,"isWritable":false,"ndefMessage":[{"tnf":1,"type":[85],"id":[],"payload":[3,112,108,97,121,46,103,111,111,103,108,101,46,99,111,109,47,115,116,111,114,101,47,97,112,112,115,47,100,101,116,97,105,108,115,63,105,100,61,99,111,109,46,119,97,107,100,101,118,46,119,100,110,102,99,38,102,101,97,116,117,114,101,61,98,101,97,109]},{"tnf":4,"type":[97,110,100,114,111,105,100,46,99,111,109,58,112,107,103],"id":[],"payload":[99,111,109,46,119,97,107,100,101,118,46,119,100,110,102,99]}],"canMakeReadOnly":false}}
Thanks in advance for your help!

Your data is at
ndefMessage[0].payload
you need to use
nfc.bytesToString()
the payload to convert to string

Related

Ionic5: setting a footer on all app pages with a sharedModule and controlling it (on/off) from the app.component

I've created a new app using Ionic5 with a menu. I'm trying to use a Footer on multiple pages (now only on Home page). First I've created a SharedModule and imported in the imports' array of the app.module.ts. I've added the footer component in the declarations' and exports' array of the shared.module.ts. Also I added SharedModule in the imports' array of each page.module.ts, and finally adding <app-footer> in each page.html.
It works as expected, showing the footer in all pages. But now I need to control (on/off) this footer from my app.component, in response to a specific event, for example, when internet is not available (this part is not a problem).
footer.component.ts
import { Component, OnInit } from '#angular/core';
import { FooterService } from 'src/app/footer.service';
#Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss'],
})
export class FooterComponent implements OnInit {
public FooterEnabled: boolean= false;
constructor() { }
ngOnInit() {
}
}
The FooterEnabled variable control if the footer is showed or not and must be modifiable from the app.component
footer.component.html
<div class="footer-conn" *ngIf="FooterEnabled">
Alert!
</div>
sharedfooter.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FooterComponent } from '../components/footer/footer.component';
#NgModule({
declarations: [FooterComponent],
imports: [
CommonModule
],
exports: [
FooterComponent, CommonModule
]
})
export class SharedFooterModule { }
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { Network } from '#ionic-native/network/ngx';
import { SharedFooterModule } from './shared/sharedfooter.module';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
SharedFooterModule
],
providers: [
StatusBar,
SplashScreen,
Network,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}
app.component.ts
import { Component, OnInit } from '#angular/core';
import { Platform } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { Network } from '#ionic-native/network/ngx';
#Component({
selector: 'app-root',
templateUrl: 'app.component.html',
styleUrls: ['app.component.scss']
})
export class AppComponent implements OnInit {
public selectedIndex = 0;
public appPages = [
{
title: 'Página 1',
url: 'home',
icon: 'mail'
},
{
title: 'Página 2',
url: 'pagina2',
icon: 'paper-plane'
},
{
title: 'Página 3',
url: 'pagina3',
icon: 'heart'
}
];
constructor(
private platform: Platform,
private splashScreen: SplashScreen,
private statusBar: StatusBar,
private network: Network
) {
this.initializeApp();
}// Fin constructor
no_internet() {
alert("No internet!")
// In this point make FooterEnabled = true (from the footer component)
}
si_internet() {
alert("Whith internet!")
//In this point make FooterEnabled = false (from the footer component)
}
initializeApp() {
this.platform.ready().then(() => {
this.statusBar.styleDefault();
this.splashScreen.hide();
});
}
ngOnInit() {
let disconnectSubscription = this.network.onDisconnect().subscribe(() => {
setTimeout(() => {
if (this.network.type !== 'none') {
this.si_internet();
}
else {
this.no_internet();
}
}, 1000);
});
// watch network for a connection
let connectSubscription = this.network.onConnect().subscribe(() => {
setTimeout(() => {
if (this.network.type !== 'none') {
this.si_internet();
}
else {
this.no_internet();
}
}, 3000);
});
const path = window.location.pathname.split('/')[1];
if (path !== undefined) {
this.selectedIndex = this.appPages.findIndex(page => page.title.toLowerCase() === path.toLowerCase());
}
}
}
home.module.ts (as an example)
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { IonicModule } from '#ionic/angular';
import { HomePageRoutingModule } from './home-routing.module';
import { HomePage } from './home.page';
import { SharedFooterModule } from '../shared/sharedfooter.module';
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
HomePageRoutingModule,
SharedFooterModule
],
declarations: [HomePage]
})
export class HomePageModule {}
I've tried with a service imported in the footer.component and app.component.ts that implements observables, but it didn't work. I will appreciate your contributions!!
maybe you can do it like bellow, add input to your footer component :
footer.component.ts
import { Component, OnInit, Input } from '#angular/core';
#Component({
selector: 'app-footer',
templateUrl: './footer.component.html',
styleUrls: ['./footer.component.scss'],
})
export class FooterComponent implements OnInit {
#Input() FooterEnabled : string;
//public FooterEnabled: boolean= false;
constructor() { }
ngOnInit() {
}
}
footer.component.ts
<div class="footer-conn" *ngIf="FooterEnabled == 'on'">
Alert!
</div>
on your app.component.ts add new varibale status:
no_internet() {
alert("No internet!")
this.status = 'on'
}
si_internet() {
alert("Whith internet!")
this.status = 'off'
}
put it on app.component.html as :
<app-footer FooterEnabled="status" ></app-footer>

Problem with HttpInterceptor in Angular 8 - HTTPInterceptor is not triggered

I have a simple code of HttpInterceptor, i'm trying to add some data in the request headr, but this is not working.
MyInterceptorService Class Code :
import { Injectable } from '#angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable()
export class MyInterceptorService implements HttpInterceptor {
constructor() { }
intercept(req:HttpRequest<any>, next:HttpHandler):Observable<HttpEvent<any>>
{
console.log("hello");
return next.handle(
req.clone({
headers: req.headers.set('Authorization', 'Bearer ')
})
);
}
}
Module Class Code
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {FormsModule} from '#angular/forms';
import { SecretComponent } from './secret/secret.component';
import { ErreurComponent } from './erreur/erreur.component';
import { HTTP_INTERCEPTORS } from '#angular/common/http';
import { MyInterceptorService } from './my-interceptor.service';
#NgModule({
declarations: [
AppComponent,
SecretComponent,
ErreurComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: MyInterceptorService,
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
The Console message is never displayed and the Http Header is not updated
Are you sure you make an HTTP-request somewhere in your code? For example:
import { Component, OnInit } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
constructor(private http: HttpClient) {}
ngOnInit() {
this.http.get('http://www.google.com')
.subscribe();
}
}
I made a Stackblitz example with copy-paste of your MyInterceptorService and it displays the console 'hello' message: https://stackblitz.com/edit/angular-rhpnjg

NullInjectorError: No provider for ReducerManager on angular spec file testing

I am testing ngrx/store based component. on test getting NullInjectorError: No provider for ReducerManager
Error message:
StaticInjectorError(Platform: core)[StoreFeatureModule -> ReducerManager]:
NullInjectorError: No provider for ReducerManager!
Error: StaticInjectorError(DynamicTestModule)[StoreFeatureModule -> ReducerManager]:
StaticInjectorError(Platform: core)[StoreFeatureModule -> ReducerManager]:
NullInjectorError: No provider for ReducerManager!
How to fix this? here is my test spec file:
import { HeaderNavShellComponent } from './header-nav-shell.component';
import { HeaderComponent } from './../../header/header.component';
import { HeaderNavComponent } from './../../components/header-nav/header-nav.component';
import { StoreModule, Store } from '#ngrx/store';
import { TranslateFakeLoader,TranslateLoader,TranslateModule,TranslateService, TranslateStore } from '#ngx-translate/core';
import { RouterTestingModule } from '#angular/router/testing';
import { reducerShared } from "./../../state/reducers/shared.reducer";
import { HttpClientModule, HttpClient } from '#angular/common/http';
import { of } from 'rxjs';
import * as fromRoot from "./../../../calendar/state";
// import { reducerCalendar } from "./../../../calendar/state/calendar.reducer";
describe('HeaderNavShellComponent', () => {
let component: HeaderNavShellComponent;
let fixture: ComponentFixture<HeaderNavShellComponent>;
let dispatchSpy;
let store:Store<fromRoot.NewState>
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ HeaderNavShellComponent, HeaderComponent, HeaderNavComponent ],
imports:[
HttpClientModule,
StoreModule.forFeature("shared", reducerShared ),
RouterTestingModule,
TranslateModule.forChild({
          loader: {
            provide: TranslateLoader,
            useClass: TranslateFakeLoader
          }
         })
],
providers:[TranslateService, TranslateStore, HttpClient ]
})
.compileComponents();
}));
beforeEach(fakeAsync(() => {
store = TestBed.get(Store);
spyOn(store, 'dispatch').and.callThrough();
fixture = TestBed.createComponent(HeaderNavShellComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', fakeAsync(() => {
expect(component).toBeTruthy();
}));
});
here is the ts file:
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { Store, select } from "#ngrx/store";
import { Observable } from "rxjs";
import { ModelEvent, EventState } from "./../../../calendar/models/model.event";
import { ModelLang, ModelLonguage } from "./../../../shared-components/models/models";
import { CalendarActions, Load, EventSelected } from "./../../../calendar/state/calendar.actions";
import * as fromRoot from "./../../../calendar/state";
import * as fromObservables from "./../../state";
import { Lang, LoadLang } from "./../../state/actions/shared.actions";
import { ShowNavi } from "./../../../shared-components/state/actions/shared.actions";
#Component({
selector: 'header-nav-shell',
templateUrl: './header-nav-shell.component.html',
styleUrls: ['./header-nav-shell.component.scss']
})
export class HeaderNavShellComponent implements OnInit {
eventList$:Observable<ModelEvent[]>;
eventListSize$:number;
currentLang$:Observable<string>;
langList$:Observable<ModelLonguage[]>;
constructor(private store:Store<fromRoot.NewState>, private router:Router) { }
ngOnInit() {
this.store.dispatch(new Load());
this.store.dispatch( new LoadLang());
this.eventList$ = this.store.pipe(select(fromRoot.getEvents));
this.currentLang$ = this.store.pipe(select(fromObservables.getCurrentLang));
this.langList$ = this.store.pipe(select(fromObservables.getLangList));
}
eventSelected(event) {
this.store.dispatch(new EventSelected(event));
this.router.navigateByUrl("iboCalendar");
}
langChanged(event) {
this.store.dispatch( new Lang(event.Name));
}
leftNaviHandler(event):void {
this.store.dispatch(new ShowNavi(event));
}
}
Thanks in advance

How to fix 'TypeError: this.form.get is not a function' in karma test runner

I am using formbuilder.group to create reactive form with the formcontrol name in ngOnInit() and made a get function for name, when I run ng test I get error as below
I have created the test case for my component using Simon Test extension
I tried importing ReactiveFormsModule, CommonModule in spec.ts
I tried changing form.get('name') to form.controls.name
Error in karma-test runner
Test1Component ngOnInit makes expected calls
TypeError: this.form.get is not a function
TypeError: this.form.get is not a function
at Test1Component.get [as name] (http://localhost:9877/_karma_webpack_/webpack:/src/app/test1/test1.component.ts:27:22)
at Test1Component../src/app/test1/test1.component.ts.Test1Component.printVal (http://localhost:9877/_karma_webpack_/webpack:/src/app/test1/test1.component.ts:23:22)
at Test1Component.SpyStrategy.exec (http://localhost:9877/absoluteC:/Users/ratnsing/Desktop/Ratnesh/Angular7/Xv1/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:5083:19)
at Test1Component.spy (http://localhost:9877/absoluteC:/Users/ratnsing/Desktop/Ratnesh/Angular7/Xv1/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:4873:44)
at Test1Component.<anonymous> (http://localhost:9877/absoluteC:/Users/ratnsing/Desktop/Ratnesh/Angular7/Xv1/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:4849:20)
at Test1Component.printVal (http://localhost:9877/absoluteC:/Users/ratnsing/Desktop/Ratnesh/Angular7/Xv1/node_modules/jasmine-core/lib/jasmine-core/jasmine.js?0b1eaf7a13cae32191eadea482cfc96ae41fc22b:4890:50)
at Test1Component../src/app/test1/test1.component.ts.Test1Component.ngOnInit (http://localhost:9877/_karma_webpack_/webpack:/src/app/test1/test1.component.ts:19:10)
at UserContext.<anonymous> (http://localhost:9877/_karma_webpack_/webpack:/src/app/test1/test1.component.spec.ts:28:17)
at ZoneDelegate../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:9877/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone.js:391:1)
at ProxyZoneSpec.push../node_modules/zone.js/dist/zone-testing.js.ProxyZoneSpec.onInvoke (http://localhost:9877/_karma_webpack_/webpack:/node_modules/zone.js/dist/zone-testing.js:289:1)
test1.component.ts
import { Component, OnInit } from '#angular/core';
import { FormGroup, FormBuilder } from '#angular/forms';
#Component({
selector: 'app-test1',
templateUrl: './test1.component.html',
styleUrls: ['./test1.component.css']
})
export class Test1Component implements OnInit {
form: FormGroup;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.form = this.formBuilder.group({
name: ['Init Value']
});
this.printval();
}
printVal() {
console.log(this.name);
}
get name() {
return this.form.get('name');
}
}
test1.component.spec.ts
import { ComponentFixture, TestBed } from '#angular/core/testing';
import { NO_ERRORS_SCHEMA } from '#angular/core';
import { FormBuilder } from '#angular/forms';
import { Test1Component } from './test1.component';
describe('Test1Component', () => {
let component: Test1Component;
let fixture: ComponentFixture<Test1Component>;
beforeEach(() => {
const formBuilderStub = { group: object1 => ({}) };
TestBed.configureTestingModule({
schemas: [NO_ERRORS_SCHEMA],
declarations: [Test1Component],
providers: [{ provide: FormBuilder, useValue: formBuilderStub }]
});
fixture = TestBed.createComponent(Test1Component);
component = fixture.componentInstance;
});
it('can load instance', () => {
expect(component).toBeTruthy();
});
describe('ngOnInit', () => {
it('makes expected calls', () => {
const formBuilderStub: FormBuilder = fixture.debugElement.injector.get(
FormBuilder
);
spyOn(component, 'printVal').and.callThrough();
spyOn(formBuilderStub, 'group').and.callThrough();
component.ngOnInit();
expect(component.printVal).toHaveBeenCalled();
expect(formBuilderStub.group).toHaveBeenCalled();
});
});
});
I found that .get is a part of AbstractControl property,
expecting al the test cases to pass...
Can u try:
import { async, ComponentFixture, TestBed } from '#angular/core/testing';
import { ReactiveFormsModule, FormBuilder, FormsModule } from '#angular/forms';
import { CommonModule } from '#angular/common';
beforeEach(async(() => {
const formBuilderStub = { group: object1 => ({}) };
TestBed.configureTestingModule({
imports: [CommonModule,ReactiveFormsModule,FormsModule],
schemas: [NO_ERRORS_SCHEMA],
declarations: [Test1Component],
providers: [FormBuilder]
}).compileComponents();
fixture = TestBed.createComponent(Test1Component);
component = fixture.componentInstance;
}));
Remove overriding of FormBuilder service
providers: [{ provide: FormBuilder, useValue: formBuilderStub }]
Import ReactiveFormsModule in TestBed
Add .compileComponents();
Put it in async block

Error: StaticInjectorError(DynamicTestModule) Angular 5 Karma Jasmine 2.8.0

My app is working fine but while i am trying to perform unit testing i am getting below mentioned error :
Error: StaticInjectorError(DynamicTestModule)[AppComponent ->
FinanceserviceService]: StaticInjectorError(Platform:
core)[AppComponent -> FinanceserviceService]:
NullInjectorError: No provider for FinanceserviceService!
My codes are given below :
financeservice.service.ts
import { Injectable } from '#angular/core';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import 'rxjs/add/operator/map';
#Injectable()
export class FinanceserviceService {
constructor(private _http: HttpClient) { }
finData() {
return this._http.get("./assets/data.json")
.map(result => result);
}
}
test.spec.ts
import { TestBed, inject,async,ComponentFixture } from '#angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '#angular/common/http/testing';
import { FinanceserviceService } from './financeservice.service';
import { AppComponent } from './XXXX.component';
import { SliderModule } from 'angular-image-slider';
import { CUSTOM_ELEMENTS_SCHEMA,NO_ERRORS_SCHEMA } from '#angular/core';
import 'rxjs/add/operator/map';
describe('FinanceserviceService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [FinanceserviceService],
schemas: [
CUSTOM_ELEMENTS_SCHEMA,
NO_ERRORS_SCHEMA
]
});
});
it(`should create`, async(inject([HttpTestingController, FinanceserviceService],
(httpClient: HttpTestingController, financeservice: FinanceserviceService) => {
expect(financeservice).toBeTruthy();
})));
});
*.component.ts
import { Component } from '#angular/core';
import { FinanceserviceService } from './financeservice.service';
import { Chart } from 'chart.js';
constructor(private _fin: FinanceserviceService){
}
ngOnInit() {
this._fin.finData()
.subscribe(res => {
let Fmax = res['list'].map(res => res.main.temp_max);
let Fmin = res['list'].map(res => res.main.temp_min);
let alldates = res['list'].map(res => res.dt)
let FDates = []
alldates.forEach((res) => {
let jsdate = new Date(res * 1000)
FDates.push(jsdate.toLocaleTimeString('en', { year: 'numeric', month: 'short', day: 'numeric' }))
})
this.chart=new Chart('canvas',{
type: 'line',
data: {
labels: FDates,
datasets: [
{
data: Fmax,
borderColor: "#3cba9f",
fill: false
},
{
data: Fmin,
borderColor: "#ffcc00",
fill: false
},
]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
}
}
})
})
}
*.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { HttpClientModule } from '#angular/common/http';
import { FinanceserviceService } from './financeservice.service';
import { NgModule,CUSTOM_ELEMENTS_SCHEMA } from '#angular/core';
import { AppComponent } from './XXX.component';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { SliderModule } from 'angular-image-slider';
import { CommonModule } from '#angular/common';
import { NO_ERRORS_SCHEMA } from '#angular/core';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
BrowserAnimationsModule,
SliderModule,
],
schemas: [NO_ERRORS_SCHEMA],
providers: [FinanceserviceService],
bootstrap: [AppComponent]
})
export class AppModule { }
Kindly help