I am trying to build a barcode scanner app with the Ionic framework. The function in scan.page.ts works fine, but unfortunately just once. After I scanned one barcode, the scanner wont open anymore.
I think it might be an issue with the ion-tabs. They only trigger the scan() function once. Afterwards the function will not get executed anymore.
scan.page.ts
import { Component, OnInit } from '@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { DataServiceService } from '../../app/data-service.service';
import { Toast } from '@ionic-native/toast/ngx';
import { Router } from '@angular/router';
import { Platform, AlertController } from '@ionic/angular';
import * as moment from 'moment';
@Component({
selector: 'app-scan',
templateUrl: './scan.page.html',
styleUrls: ['./scan.page.scss'],
})
export class ScanPage implements OnInit {
productViews: any = {};
productViewsbyUser: any[] = [];
isProdcutsAvailable = true;
selectedProduct: any;
isCameraOpen = false;
showScan = false;
products: any[] = [];
productFound = true;
displayUserName: any;
exitModalDisplayed = false;
constructor(
private barcodeScanner: BarcodeScanner,
private router: Router,
public platform: Platform,
private toast: Toast,
public dataService: DataServiceService,
public alertCtrl: AlertController) {
console.log(`Scan Page called`);
}
ngOnInit() {
this.dataService.getProducts()
.subscribe((response) => {
this.products = <any[]><unknown>response;
console.table(this.products);
});
this.scan();
this.handleBackButton();
}
getMoment() {
return moment().milliseconds(0);
}
// Start scanning procedure
scan() {
this.selectedProduct = {};
this.isCameraOpen = true;
this.showScan = true;
this.barcodeScanner.scan().then((barcodeData) => {
setTimeout(() => {
this.isCameraOpen = false;
}, 500);
if (barcodeData.cancelled) {
return;
}
console.log(`barcodeData`, barcodeData);
this.selectedProduct = this.products.find(product => product.plu === barcodeData.text);
if (this.selectedProduct !== undefined) {
this.selectedProduct.scannedAt = this.getMoment().toISOString();
// this.selectedProduct.userName = this.displayUserName(); // TO TEST !!!
this.productFound = true;
// insert product views with firebase generated based key
this.dataService.insertProductViewAnalaytics(this.selectedProduct)
.subscribe(() => {
console.log(`Product view analytics inserted in Firebase`);
this.initScanHistoryData();
});
} else {
this.productFound = false;
this.toast.show(`Product not found`, '5000', 'center').subscribe(
toast => {
console.log(toast);
}
);
}
}, (err) => {
setTimeout(() => {
this.isCameraOpen = false;
}, 1000);
this.toast.show(err, '5000', 'center').subscribe(
toast => {
console.log(toast);
}
);
});
}
async initScanHistoryData() {
this.dataService.getProductViewsForUser()
.subscribe((response) => {
this.productViews = response;
const userProductViews = [];
// tslint:disable-next-line: forin
for (const key in this.productViews) {
userProductViews.push(this.productViews[key]);
}
userProductViews.sort(function (a, b) {
return moment(b.scannedAt).diff(moment(a.scannedAt));
// ENTER USER NAME HERE???
});
this.productViewsbyUser = userProductViews;
console.log('user productViews ', userProductViews);
if (this.productViewsbyUser.length) {
this.isProdcutsAvailable = true;
} else {
this.isProdcutsAvailable = false;
}
console.log('productViews ', this.productViews);
});
}
handleBackButton() {
this.platform.backButton.subscribeWithPriority(9999, () => {
console.log('exit');
if (this.exitModalDisplayed || this.isCameraOpen) {
return;
}
this.exitModalDisplayed = true;
const alert = this.alertCtrl.create({
header: 'Do you want to Exit?',
// message: 'Do you want Exit?',
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: () => {
console.log('Cancel clicked');
this.exitModalDisplayed = false;
}
},
{
text: 'Yes',
handler: () => {
console.log('Confirm Okay');
navigator['app'].exitApp();
}
}
]
});
alert.then(x => x.present());
});
}
}
tabs.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/mon';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
import { IonicModule } from '@ionic/angular';
import { TabsPage } from './tabs.page';
const routes: Routes = [
{
path: 'tabs',
ponent: TabsPage,
children: [
{ path: 'profile', loadChildren: '../profile/profile.module#ProfilePageModule' },
{ path: 'products', loadChildren: '../products/products.module#ProductsPageModule' },
{ path: 'scan', loadChildren: '../scan/scan.module#ScanPageModule' },
]
},
{
path: '',
redirectTo: '/tabs/products',
pathMatch: 'full'
}
];
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild(routes)
],
declarations: [TabsPage]
})
export class TabsPageModule {}
tabs.page.html
<ion-tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="products">
<ion-icon name="md-list"></ion-icon>
<ion-label>Products</ion-label>
<!-- <ion-badge>6</ion-badge> -->
</ion-tab-button>
<ion-tab-button tab="scan">
<ion-icon name="md-qr-scanner"></ion-icon>
<ion-label>Scan</ion-label>
</ion-tab-button>
<ion-tab-button tab="profile">
<ion-icon name="md-person"></ion-icon>
<ion-label>Profile</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
I expect that the scanner gets opened every time the scan tab button gets pressed.
I am trying to build a barcode scanner app with the Ionic framework. The function in scan.page.ts works fine, but unfortunately just once. After I scanned one barcode, the scanner wont open anymore.
I think it might be an issue with the ion-tabs. They only trigger the scan() function once. Afterwards the function will not get executed anymore.
scan.page.ts
import { Component, OnInit } from '@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { DataServiceService } from '../../app/data-service.service';
import { Toast } from '@ionic-native/toast/ngx';
import { Router } from '@angular/router';
import { Platform, AlertController } from '@ionic/angular';
import * as moment from 'moment';
@Component({
selector: 'app-scan',
templateUrl: './scan.page.html',
styleUrls: ['./scan.page.scss'],
})
export class ScanPage implements OnInit {
productViews: any = {};
productViewsbyUser: any[] = [];
isProdcutsAvailable = true;
selectedProduct: any;
isCameraOpen = false;
showScan = false;
products: any[] = [];
productFound = true;
displayUserName: any;
exitModalDisplayed = false;
constructor(
private barcodeScanner: BarcodeScanner,
private router: Router,
public platform: Platform,
private toast: Toast,
public dataService: DataServiceService,
public alertCtrl: AlertController) {
console.log(`Scan Page called`);
}
ngOnInit() {
this.dataService.getProducts()
.subscribe((response) => {
this.products = <any[]><unknown>response;
console.table(this.products);
});
this.scan();
this.handleBackButton();
}
getMoment() {
return moment().milliseconds(0);
}
// Start scanning procedure
scan() {
this.selectedProduct = {};
this.isCameraOpen = true;
this.showScan = true;
this.barcodeScanner.scan().then((barcodeData) => {
setTimeout(() => {
this.isCameraOpen = false;
}, 500);
if (barcodeData.cancelled) {
return;
}
console.log(`barcodeData`, barcodeData);
this.selectedProduct = this.products.find(product => product.plu === barcodeData.text);
if (this.selectedProduct !== undefined) {
this.selectedProduct.scannedAt = this.getMoment().toISOString();
// this.selectedProduct.userName = this.displayUserName(); // TO TEST !!!
this.productFound = true;
// insert product views with firebase generated based key
this.dataService.insertProductViewAnalaytics(this.selectedProduct)
.subscribe(() => {
console.log(`Product view analytics inserted in Firebase`);
this.initScanHistoryData();
});
} else {
this.productFound = false;
this.toast.show(`Product not found`, '5000', 'center').subscribe(
toast => {
console.log(toast);
}
);
}
}, (err) => {
setTimeout(() => {
this.isCameraOpen = false;
}, 1000);
this.toast.show(err, '5000', 'center').subscribe(
toast => {
console.log(toast);
}
);
});
}
async initScanHistoryData() {
this.dataService.getProductViewsForUser()
.subscribe((response) => {
this.productViews = response;
const userProductViews = [];
// tslint:disable-next-line: forin
for (const key in this.productViews) {
userProductViews.push(this.productViews[key]);
}
userProductViews.sort(function (a, b) {
return moment(b.scannedAt).diff(moment(a.scannedAt));
// ENTER USER NAME HERE???
});
this.productViewsbyUser = userProductViews;
console.log('user productViews ', userProductViews);
if (this.productViewsbyUser.length) {
this.isProdcutsAvailable = true;
} else {
this.isProdcutsAvailable = false;
}
console.log('productViews ', this.productViews);
});
}
handleBackButton() {
this.platform.backButton.subscribeWithPriority(9999, () => {
console.log('exit');
if (this.exitModalDisplayed || this.isCameraOpen) {
return;
}
this.exitModalDisplayed = true;
const alert = this.alertCtrl.create({
header: 'Do you want to Exit?',
// message: 'Do you want Exit?',
buttons: [
{
text: 'Cancel',
role: 'cancel',
cssClass: 'secondary',
handler: () => {
console.log('Cancel clicked');
this.exitModalDisplayed = false;
}
},
{
text: 'Yes',
handler: () => {
console.log('Confirm Okay');
navigator['app'].exitApp();
}
}
]
});
alert.then(x => x.present());
});
}
}
tabs.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/mon';
import { FormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
import { IonicModule } from '@ionic/angular';
import { TabsPage } from './tabs.page';
const routes: Routes = [
{
path: 'tabs',
ponent: TabsPage,
children: [
{ path: 'profile', loadChildren: '../profile/profile.module#ProfilePageModule' },
{ path: 'products', loadChildren: '../products/products.module#ProductsPageModule' },
{ path: 'scan', loadChildren: '../scan/scan.module#ScanPageModule' },
]
},
{
path: '',
redirectTo: '/tabs/products',
pathMatch: 'full'
}
];
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild(routes)
],
declarations: [TabsPage]
})
export class TabsPageModule {}
tabs.page.html
<ion-tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="products">
<ion-icon name="md-list"></ion-icon>
<ion-label>Products</ion-label>
<!-- <ion-badge>6</ion-badge> -->
</ion-tab-button>
<ion-tab-button tab="scan">
<ion-icon name="md-qr-scanner"></ion-icon>
<ion-label>Scan</ion-label>
</ion-tab-button>
<ion-tab-button tab="profile">
<ion-icon name="md-person"></ion-icon>
<ion-label>Profile</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
I expect that the scanner gets opened every time the scan tab button gets pressed.
Share Improve this question edited Nov 6, 2019 at 8:34 vlntn asked Nov 6, 2019 at 8:20 vlntnvlntn 3708 silver badges24 bronze badges2 Answers
Reset to default 3try to another methode, that is using ionViewWillEnter()
in your target tab, that is solve my problem too
Right now, your scan()
function is only executed when ngOnInit()
is called.
If you want to execute it every time a user clicks on the tab you can do something like:
<ion-tab-button tab="scan" (click)="scan()">
<ion-icon name="md-qr-scanner"></ion-icon>
<ion-label>Scan</ion-label>
</ion-tab-button>