Last week, I was super excited to figure out how to provision IBM Cloudant / CouchDB databases during an Auth0 login transaction . This allows me to drive a database-per-user architecture on the remote side; and, thanks to PouchDB, I can do the same thing on the local side. The last piece of the puzzle was being able to keep the remote Cloudant database and the local PouchDB database in sync. Thankfully, the CouchDB replication API, leveraged by the PouchDB client library, makes this super easy!

Run this demo in my javascript Demos project on GitHub .

Replication between two CouchDB-compatible databases happens in a single direction - a source database replicates to a target database. But, thanks to the magical master-master replication capabilities of CouchDB, bi-directional replication can be achieved by essentially performing uni-directional replication in both directions. In the PouchDB client library, they even provide a convenience method for this bi-directional replication setup, called .sync().


Syncing Local PouchDB Data With Remote IBM Cloudant Database In Angular 2.4.1

The .sync() method can perform replication in a discrete, one-off manor; or, it can perform "live" syncing in which the target database is "long polled" for updates that need to be replicated back down to the source database. In my exploration, I am performing discrete sync operations for a few reasons:

First, I don't believe that IBM Cloudant allows for "live sync" by default (though I also believe that I may be confusing the terminology, assuming that "continuous replication" and "live sync" are the same thing). Based on the documentation, it appears to be disabled for both performance and cost reasons - both of which relate to reducing network activity. Second, I think it might make more sense from an "offline first" web application perspective to perform synchronization at specific points in the application life-cycle. Focus on the local experience first; then, figure out when it makes sense to sync to the remote database (balancing user experience with an actual dollars-and-cents cost).

To explore data synchronization across CouchDB instances, I took my previous Angular 2 demo in which I deferred PouchDB configuration until after login ; then, I added some remote database credentials (hard-coded) and an explicit syncing function. In this case, since the demo has two "users", I went into Cloudant, provisioned two new databases and, for each database, assigned a new API Key that had read, write, and replicate permissions.

First, let's look at the Angular 2 root component. In this component, the user can log into the application using one of two hard-coded identities. Once "authenticated", both a local and remote PouchDB database are provisioned and the list of friends is loaded. The user can then interact with the list of friends, adding and deleting entires. These mutations are performed against the local PouchDB database only. When the user selects to "sync" the two databases, however, changes are pushed and pulled between the local and remote databases and the list of friends is re-rendered:

// Import the core angular services. import { Component } from "@angular/core"; // Import the application components and services. import { FriendService } from "./friend.service"; import { IFriend } from "./friend.service"; import { ISyncResult } from "./pouchdb.service"; import { PouchDBService } from "./pouchdb.service"; interface IAddForm { name: string; @Component({ moduleId: module.id, selector: "my-app", styleUrls: [ "./app.component.css" ], template: <!-- BEIGN: Logged-out view. --> <template [ngIf]="( user === null )"> <ul> <li> <a (click)="login( 'ben' )">Login as Ben</a> </li> <li> <a (click)="login( 'kim' )">Login as Kim</a> </li> </ul> </template> <!-- END: Logged-out view. --> <!-- BEIGN: Logged-in view. --> <template [ngIf]="( user !== null )"> <p> <strong>Logged-in as {{ user }}</strong>. <a (click)="logout()">Logout</a> &nbsp;|&nbsp; <a (click)="syncData()">Sync remote database</a>. </p> <ul> <li *ngFor="let friend of friends"> {{ friend.name }} &mdash; <a (click)="deleteFriend( friend )">Delete</a> </li> </ul> <div class="form"> <input type="text" [value]="addForm.name" (input)="addForm.name = $event.target.value" (keydown.Enter)="processAddForm()" /> <button type="button" (click)="processAddForm()">Add Friend</button> </div> </template> <!-- END: Logged-in view. --> }) export class AppComponent { public addForm: IAddForm; public friends: IFriend[]; public user: string; private friendService: FriendService; private pouchdbService: PouchDBService; // I initialize the component. constructor( friendService: FriendService, pouchdbService: PouchDBService ) { this.friendService = friendService; this.pouchdbService = pouchdbService; this.addForm = { name: "" }; // To start out, the Friends collection will be empty; and, it must remain // empty until the user logs-in because, until then, the PouchDB database has // not been configured and we won't know where to read data from. this.friends = []; this.user = null; // --- // PUBLIC METHODS. // --- // I delete the given friend from the list. public deleteFriend( friend: IFriend ) : void { this.friendService .deleteFriend( friend.id ) .then( () : void => { this.loadFriends(); }, ( error: Error ) : void => { console.log( "Error:", error ); // I login the user with the given identifier. public login( userIdentifier: string ) : void { // In

本文数据库(综合)相关术语:系统安全软件

主题: CouchDBIBMGitJavaScriptGitHubJavaUBETH
分页:12
转载请注明
本文标题:Syncing Local PouchDB Data With Remote IBM Cloudant Database In Angular 2.4.1
本站链接:http://www.codesec.net/view/524510.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 数据库(综合) | 评论(0) | 阅读(95)