I am a beginner and developing a mobile app using Cordova, ionic 2 and couchbase lite. I want to store the different types of documents and retrieve the data from the documents. I have developed the code using the sample provided in the link https://blog.couchbase.com/2016/december/data-synchronization-with-couchbase-in-ionic-2-hybrid-mobile-apps. First task: I want retrieve the data when an event (like button click) is occurred; not when an update in database takes place. Second Task: I want to retrieve the data from different types of documents.
I changed the couchbase-provider.ts as follows:
import { Injectable, EventEmitter } from ‘@angular/core’;
import { Http } from ‘@angular/http’;
import { Platform } from ‘ionic-angular’;
import { Couchbase, Database } from “cordova-couchbase/core”;
import ‘rxjs/add/operator/map’;
declare var emit: any;
@Injectable()
export class CouchbaseProvider {
private isInstantiated: boolean;
private database: Database;
//create a listener
private listener: EventEmitter<any> = new EventEmitter();
public constructor(public http: Http, platform: Platform) {
if(!this.isInstantiated) {
//do when the platform is ready
platform.ready().then(() => {
//Create and open the database with the specified name, if it doesnot exist
//otherwise open the database
(new Couchbase()).openDatabase("netzone").then(database => {
//asign the database instance to the local variable
this.database = database;
//create a mapreduce view (agentViews) with name agents if the document contains
//property called type as agentDetails and any value in fName
let agentViews = {
agents: {
map: function(doc) {
if(doc.type == "agentDetails" && doc.fName) {
//emit the document id and
emit(doc._id, {fName: doc.fName, rev: doc._rev})
}
}.toString()
}
};
//create a mapreduce view (loanViews) with name loans if the document contains
//property called type as loandetails and any value in loantype
let loanViews = {
loans: {
map: function(doc) {
if(doc.type == "loandetails" && doc.loantype) {
//emit the document id and
emit(doc._id, {loantype: doc.loantype, rev: doc._rev})
}
}.toString()
}
};
//create a design document for agent views
this.database.createDesignDocument("_design/agents", agentViews);
//create a design document for loans view
this.database.createDesignDocument("_design/loans", loanViews);
//when there a change in the database, emit the changes
this.database.listen(change => {
this.listener.emit(change.detail);
});
//configure the sync gateway
this.database.sync("http://127.0.0.1:4984/netzone", true);
this.isInstantiated = true;
}, error => {
console.error(error);
});
});
}
}
public getDatabase() {
return this.database;
}
public getChangeListener(): EventEmitter<any> {
return this.listener;
}
public fetch() {
return this.database.getAllDocuments.toString();
}
}
In a dailypay.ts I add the following functions to store and retrieve the data.
public createLoan()
{
let loandetails = {
“type”: “loandetails”,
“loantype”: this.loanType,
“loanamount”: this.loanAmount,
“intrate”:this.interestRate,
“noofinstallments”:this.noOfInstallments,
“downpayment”:this.downPayment,
“loandate”:this.currentDate
};
this.couchbase.getDatabase().createDocument(loandetails).then((result:any)=>{
Toast.show(“Loan issued and account created.”, ‘long’, ‘center’).subscribe(
toast => {
console.log(toast);
});
},errors=>
{
Toast.show(“Failed to create a loan account.”, ‘long’, ‘center’).subscribe(
toast => {
console.log(toast);
});
});
}
public showLoanDetails(){
setTimeout(() => {
//catch the data when the emiter emits the modified data
this.couchbase.getChangeListener().subscribe(data => {
//loop to iterate through the records in the data
for (let i = 0; i < data.length; i++) {
//retrive all the documents which are changed or added, and ignore deleted
if (!data[i].hasOwnProperty("deleted") && data[i].id.indexOf("_design") === -1) {
//read the document based on the document Id
this.couchbase.getDatabase().getDocument(data[i].id).then((result: any) => {
//check the result contains the key type with value agantDetails
if (result.type === "loandetails") {
//call the angular run method to dynamically update the UI controls
this.zone.run(() => {
//push the result and add it to the array
this.loans.push(result);
//display the tost message with the document ID
Toast.show("Loan type details pushed"+result.loanType, '7000', 'center').subscribe(
toast => {
console.log(toast);
});
Toast.show("Loan intrest details pushed"+result.interestRate, '8000', 'center').subscribe(
toast => {
console.log(toast);
});
Toast.show("Loan downpay details pushed"+result.downPayment, '9000', 'center').subscribe(
toast => {
console.log(toast);
});
});
}
});
}
}
});
//call the refresh method
this.refresh();
}, 100);
}
public refresh() {
//query the database using the design document and get the results
this.couchbase.getDatabase().queryView("_design/loans", "loans", {}).then((result: any) => {
this.loans = [];
//loop to read the documents as JSON objects and store them in the items array
for(var i = 0; i < result.rows.length; i++) {
this.loans.push(result.rows[i].value);
}
}, error => {
console.error("ERROR: " + JSON.stringify(error));
});
}
In dailypay.html i used the following code:
<button ion-button secondary (click)=“createLoan()”>Issue Loan
<button ion-button secondary (click)=“showLoanDetails()”>Show Loans
<ion-card>
<ion-item>
<ion-label>Agent's Details</ion-label>
</ion-item>
<ion-item *ngFor="let loan of loans">
<ion-item>{{ loan.loanAmount }}</ion-item>
<ion-item>{{ loan.interestRate }}</ion-item>
</ion-item>
</ion-card>
Similarly in the other file createagent.ts i used the following functions:
public createAgent()
{
let userdetails = {
“type”:“agentDetails”,
“fName”: this.firstName,
“lName”: this.lastName,
“dateofBirth”: this.dateofBirth,
“aadharNumber”:this.aadharNumber,
“panNumber”:this.panNumber,
“mobileNumber”:this.mobileNumber,
“userName”:this.userName,
“password”:this.password,
“confPassword”:this.confPassword
};
this.couchbase.getDatabase().createDocument(userdetails).then((result:any)=>{
Toast.show(“Agent account created.”, ‘short’, ‘center’).subscribe(
toast => {
console.log(toast);
});
},errors=>
{
Toast.show(“Failed to create an account for the user.”, ‘short’, ‘center’).subscribe(
toast => {
console.log(toast);
});
});
}
public showAgents() {
setTimeout(() => {
//catch the data when the emiter emits the modified data
this.couchbase.getChangeListener().subscribe(data => {
//loop to iterate through the records in the data
for (let i = 0; i < data.length; i++) {
//retrive all the documents which are changed or added, and ignore deleted
if (!data[i].hasOwnProperty("deleted") && data[i].id.indexOf("_design") === -1) {
//read the document based on the document Id
this.couchbase.getDatabase().getDocument(data[i].id).then((result: any) => {
//check the result contains the key type with value agantDetails
if (result.type === "agentDetails") {
//call the angular run method to dynamically update the UI controls
this.zone.run(() => {
//push the result and add it to the array
this.items.push(result);
//display the tost message with the document ID
Toast.show("Agent firts name details pushed"+result.fName, '6000', 'center').subscribe(
toast => {
console.log(toast);
});
//display the tost message with the document ID
Toast.show("Agent last name details pushed"+result.lName, '8000', 'center').subscribe(
toast => {
console.log(toast);
});
});
}
});
}
}
});
//call the refresh method
this.refresh();
}, 100);
}
public refresh() {
//query the database using the design document and get the results
this.couchbase.getDatabase().queryView("_design/agents", "items", {}).then((result: any) => {
this.items = [];
//loop to read the documents as JSON objects and store them in the items array
for(var i = 0; i < result.rows.length; i++) {
this.items.push(result.rows[i].value);
}
}, error => {
console.error("ERROR: " + JSON.stringify(error));
});
}
and in createagent.ts i used the following code:
<button ion-button secondary (click)="createAgent()">Create User Account</button>
<!--Button to show all agents account details-->
<button ion-button secondary (click)="showAgents()">Show Agents</button>
<ion-item>
<ion-label>Agent's Details</ion-label>
</ion-item>
<ion-item *ngFor="let item of items">
<ion-item>{{ item.fName }}</ion-item>
<ion-item>{{ item.lName }}</ion-item>
</ion-item>