I’m trying to build a simple mobile app that stores can add, view, edit and delete stock using an SQLite DB. I’ve been sitting for days trying to just add information and view it, but I can’t seem to simply open the database.
I’m new to Ionic and would like to know how to get started. I posted my code snippets and the error message I’m battling with when running Ionic serve. No luck when compiling on my android device because I can’t even navigate past my login screen.
Database.service.ts:
import { Platform } from '@ionic/angular';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite/ngx';
import { BehaviorSubject, Observable } from 'rxjs';
import { Storage } from '@ionic/storage';
@Injectable({
providedIn: 'root'
})
export class DatabaseService {
flavour = {};
database: SQLiteObject;
private databaseReady: BehaviorSubject<boolean>;
constructor(private http: HttpClient, private storage: Storage, private sqlite: SQLite, private platform: Platform) {
this.databaseReady = new BehaviorSubject(false);
this.platform.ready().then(() => {
this.sqlite.create({
name: 'coffeestock.db',
location: 'default'
})
.then((db: SQLiteObject) => {
this.database = db;
this.storage.get('database_filled').then(val => {
if(val) {
this.databaseReady.next(true);
} else {
this.addCofeeStock(this.flavour['barcode'], this.flavour['name'], this.flavour['pricePerBox'], this.flavour['pricePerPod'], this.flavour['podsPerBox'], this.flavour['photoName']);
}
})
}).catch(e => console.log(e));
});
}
addCofeeStock(barcode, name, pricePerBox, pricePerPod, podsPerBox, photoName) {
let data = [barcode, name, pricePerBox, pricePerPod, podsPerBox, photoName];
return this.database.executeSql("INSERT INTO Flavours (barcode, name, pricePerBox, pricePerPod, podsPerBox, photoName) VALUES (?, ?, ?, ?, ?, ?)", data).then(res => {
return res;
});
}
showStock() {
return this.database.executeSql("SELECT * FROM Flavours", []).then(data => {
let flavours = [];
if (data.row.lenght > 0) {
for (var i = 0; i < data.row.lenght; i++) {
flavours.push({barcode: data.rows.item(i).barcode, name: data.rows.item(i).name, pricePerBox: data.rows.item(i).pricePerBox, pricePerPod: data.rows.item(i).pricePerPod, podsPerBox: data.rows.item(i).podsPerBox, photoName: data.rows.item(i).photoName})
}
}
return flavours;
}, err => {
console.log('Error: ', err);
return [];
})
}
getDatabaseState() {
return this.databaseReady.asObservable();
}
}
edit-flavours.page.ts: (in this view I add the data)
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
import { Router } from '@angular/router';
import { Camera, CameraOptions, PictureSourceType } from '@ionic-native/camera/ngx';
import { ActionSheetController, ToastController, Platform, LoadingController } from '@ionic/angular';
import { File } from '@ionic-native/File/ngx';
import { HttpClient } from '@angular/common/http';
import { WebView } from '@ionic-native/ionic-webview/ngx';
import { Storage } from '@ionic/storage';
import { BarcodeScanner, BarcodeScannerOptions } from '@ionic-native/barcode-scanner/ngx';
import { DatabaseService } from 'src/app/services/database.service';
@Component({
selector: 'app-edit-flavours',
templateUrl: './edit-flavours.page.html',
styleUrls: ['./edit-flavours.page.scss'],
})
export class EditFlavoursPage implements OnInit {
myphoto:any;
options: BarcodeScannerOptions;
scannedData:any={};
flavours = [];
flavour = {};
constructor(private router: Router, private camera: Camera, private file: File, private http: HttpClient, private webview: WebView,
private storage: Storage, private actionSheetController: ActionSheetController, private toastController: ToastController,
private plt: Platform, private loadingController: LoadingController, private ref: ChangeDetectorRef,
private barcodeScanner: BarcodeScanner, private databaseService: DatabaseService) {
this.databaseService.getDatabaseState().subscribe(rdy => {
if (rdy) {
this.loadCofeeStock();
}
})
}
loadCofeeStock() {
this.databaseService.showStock().then(data => {
this.flavours = data;
});
}
ngOnInit() {
}
toCoffeeFlavours() {
this.router.navigateByUrl('/coffee-flavours');
}
async selectImage() {
const actionSheet = await this.actionSheetController.create({
header: "Select Image source",
buttons: [{
text: 'Load from Library',
handler: () => {
this.getImage()
}
},
{
text: 'Use Camera',
handler: () => {
this.takePicture();
}
},
{
text: 'Cancel',
role: 'cancel'
}
]
});
await actionSheet.present();
}
takePicture() {
const options: CameraOptions = {
quality: 70,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64 (DATA_URL):
this.myphoto = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
// Handle error
});
}
getImage() {
const options: CameraOptions = {
quality: 70,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
saveToPhotoAlbum:false
}
this.camera.getPicture(options).then((imageData) => {
// imageData is either a base64 encoded string or a file URI
// If it's base64 (DATA_URL):
this.myphoto = 'data:image/jpeg;base64,' + imageData;
}, (err) => {
// Handle error
});
}
scan() {
this.options= {
prompt: 'Scan Barcode'
};
this.barcodeScanner.scan(this.options).then((data) => {
this.scannedData = data;
}, (err) => {
console.log('Error :', err);
})
}
}
coffee-flavours.page.ts (In this view I read the data)
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { DatabaseService } from 'src/app/services/database.service';
@Component({
selector: 'app-coffee-flavours',
templateUrl: './coffee-flavours.page.html',
styleUrls: ['./coffee-flavours.page.scss'],
})
export class CoffeeFlavoursPage implements OnInit {
flavours = [];
flavour = {};
constructor(private router: Router, private databaseService: DatabaseService) {
this.databaseService.getDatabaseState().subscribe(rdy => {
if (rdy) {
this.loadCofeeStock();
}
})
}
loadCofeeStock() {
this.databaseService.showStock().then(data => {
this.flavours = data;
});
}
addCofeeStock() {
this.databaseService.addCofeeStock(this.flavour['barcode'], this.flavour['name'], this.flavour['pricePerBox'], this.flavour['pricePerPod'], this.flavour['podsPerBox'], this.flavour['photoName'])
.then(data => {
this.loadCofeeStock();
});
this.flavour = {};
}
ngOnInit() {
}
manageFlavour() {
this.router.navigateByUrl('/coffee-flavours/id');
}
}
Error in Chrome Dev tools. It refers to line 25 in my service document, but debugging doesn’t reveal anything.
core.js:9110 ERROR Error: Uncaught (in promise): TypeError: Cannot read property ‘then’ of undefined
TypeError: Cannot read property ‘then’ of undefined
at database.service.ts:25
Any help to at least get started will be great.