Retrieve multiple documents of different types form Couchbase Lite using Ionic 2 (couchbase-cordova plugin) and when an event like button click occured

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>

First task: I want retrieve the data when an event (like button click) is occurred; not when an update in database takes place.

Use the database change listener GitHub - couchbaselabs/cordova-couchbase: Generic JavaScript / TypeScript wrapper for Apache Cordova projects

Second Task: I want to retrieve the data from different types of documents.

Create a view and then query it.

Thank you for the reply. I did as you said. But I don’t know why its not working. I will try once again.
For the first task, I want to get the data when a button click event is occurred, not when the data change occurred. If possible can you suggest changes in my code.

At last, I found the way to do the task:

I modified the showAgents() as in createagent.ts follows:

public showAgents() {
        //query the database using the design document and get the results
        this.chitProvider.getDatabase().queryView("_design/agentsDesign", "agents", {}).then((agentsDesignResult: any) => {
            this.agentsArray = [];
            //loop to read the documents as JSON objects and store them in the items array
            for(var i = 0; i < agentsDesignResult.rows.length; i++) {
                this.chitZone.run(() => {
                    this.agentsArray.push(agentsDesignResult.rows[i].value);
                });               
            }
            }, error => {
                console.error("ERROR: " + JSON.stringify(error));
            });
    }
}

Changed the button click event in agents.html as follows:

        <button ion-button secondary (click)="showAgents()">Show Agents</button>        
        <ion-item>
            <ion-label>Agent's Details</ion-label>            
        </ion-item>
        
        <ion-item *ngFor="let agt of agentsArray">
            <ion-item>{{ agt.fName }}</ion-item>
            <ion-item>{{ agt.lName }}</ion-item>
        </ion-item>

Now the data in the page will be displayed only when the button is pressed.