{"id":2477,"date":"2017-01-05T15:00:00","date_gmt":"2017-01-05T15:00:00","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2477"},"modified":"2025-06-13T20:15:35","modified_gmt":"2025-06-14T03:15:35","slug":"using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/","title":{"rendered":"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB"},"content":{"rendered":"<p>Last year I wrote an article that explained how to <a href=\"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/\">synchronize between platforms and Couchbase with only AngularJS and PouchDB<\/a>. Back then AngularJS was booming and probably my favorite framework of all time. A year later AngularJS is still around, but is slowly being replaced by Angular 2, the next version of the popular framework. After using Angular 2, I look back at AngularJS 1.0 and wonder what was going through my brain because Angular 2 is pure awesomeness.<\/p>\n<p>This time around we&#8217;re going to see how to create a simple web application that syncs using only Angular 2, PouchDB, and Couchbase Mobile.<\/p>\n<h2 id=\"the-requirements\">The Requirements<\/h2>\n<p>The few requirements to being successful with this project are as follows:<\/p>\n<ul>\n<li>Node.js 4.0+<\/li>\n<li>Angular 2 CLI<\/li>\n<li><a href=\"https:\/\/github.com\/typings\/typings\">Typings<\/a><\/li>\n<li>Couchbase Sync Gateway<\/li>\n<\/ul>\n<p>The Angular 2 CLI can be installed using the Node Package Manager (NPM) which is included with Node.js. NPM is also used when it comes to gathering various project dependencies. We won&#8217;t be using Couchbase Server in this example, but we could. Instead we&#8217;re only going to use Couchbase Sync Gateway and its prototyping features.<\/p>\n<h2 id=\"configuring-couchbase-sync-gateway\">Configuring Couchbase Sync Gateway<\/h2>\n<p>Couchbase Sync Gateway is necessary to handle all of the synchronization. Without it we only have local storage in our web application, and in all honesty, there are much better solutions than PouchDB if you only wanted local storage.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/nosql-databases\/downloads\/\">Download<\/a> the latest Sync Gateway and deploy it with the following configuration:<\/p>\n<pre><code>{\r\n    \"log\":[\"CRUD+\", \"REST+\", \"Changes+\", \"Attach+\"],\r\n    \"databases\": {\r\n        \"example\": {\r\n            \"server\":\"walrus:\",\r\n            \"sync\":`\r\n                function (doc) {\r\n                    channel (doc.channels);\r\n                }\r\n            `,\r\n            \"users\": {\r\n                \"GUEST\": {\r\n                    \"disabled\": false,\r\n                    \"admin_channels\": [\"*\"]\r\n                }\r\n            }\r\n        }\r\n    },\r\n    \"CORS\": {\r\n        \"Origin\": [\"https:\/\/localhost:4200\"],\r\n        \"LoginOrigin\": [\"https:\/\/localhost:4200\"],\r\n        \"Headers\": [\"Content-Type\"],\r\n        \"MaxAge\": 17280000\r\n    }\r\n}<\/code><\/pre>\n<p>Save this to a file called <strong>sync-gateway-config.json<\/strong> if you wanted. This is a very basic configuration where we are using an <a href=\"https:\/\/www.couchbase.com\/resources\/concepts\/in-memory-database\/\">in-memory database<\/a> called <strong>example<\/strong>. There are no read and write permissions so anything goes. At the bottom of this configuration we have some items relating to cross origin resource sharing (CORS). Because we&#8217;ll be serving our application locally, we need to identify this to prevent JavaScript errors.<\/p>\n<h2 id=\"creating-a-new-angular-2-project\">Creating a New Angular 2 Project<\/h2>\n<p>To make things easy to understand we&#8217;re going to create a project with an incredibly simplistic design. We&#8217;re going to create a simple user management application where we can add people and they will be synchronized to wherever you want. For example, check the animation below:<\/p>\n<div class=\"figure\"><img decoding=\"async\" src=\"\/wp-content\/original-assets\/2017\/january\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/pouchdb-angular2-cbmobile.gif\" alt=\"Couchbase with PouchDB and Angular 2\" \/><\/div>\n<p>In the above animation we have two web browsers. Add a person to one and it will synchronize to the other. This is something that would be particularly difficult without Couchbase.<\/p>\n<p>Let&#8217;s start by creating a fresh Angular 2 project using the Angular CLI. Execute the following from your Command Prompt (Windows) or Terminal (Mac and Linux):<\/p>\n<pre><code>ng new PouchDBProject<\/code><\/pre>\n<p>It may take a while, but when the project is created we want to install PouchDB and any necessary dependencies. Execute the following to install the latest PouchDB:<\/p>\n<pre><code>npm install pouchdb --save<\/code><\/pre>\n<p>The maintainers of PouchDB have mixed emotions when it comes to TypeScript, a critical technology when it comes to Angular 2 development. For this reason there are no reliable type definitions available. This is not a big deal though.<\/p>\n<p>Using Typings, we are going to install the following:<\/p>\n<pre><code>typings install dt~require --save --global<\/code><\/pre>\n<p>The above type definitions will allow us to use the <code>require<\/code> keyword within TypeScript. With it we can import the downloaded PouchDB into our project.<\/p>\n<p>At this point we can start developing our project!<\/p>\n<h2 id=\"developing-an-angular-2-provider-to-maintain-the-data\">Developing an Angular 2 Provider to Maintain the Data<\/h2>\n<p>When working with data it is always a good idea to create an Angular 2 service, also known as a provider. This allows us to have a singleton instance and a class that is segregated from the rest of our code. It is great from a maintainability perspective.<\/p>\n<p>You can create the provider manually or using the CLI. From the CLI, execute the following:<\/p>\n<pre><code>ng g service pouchdb<\/code><\/pre>\n<p>Two files should be created in your project&#8217;s <strong>src\/app<\/strong> directory. You should have a <strong>pouchdb.service.ts<\/strong> and a <strong>pouchdb.service.spec.ts<\/strong> file. They may be named something similar, but the name isn&#8217;t really important.<\/p>\n<p>The <strong>spec<\/strong> file is a unit testing file, something we won&#8217;t worry about in this particular example. Instead we&#8217;re going to start developing in the <strong>pouchdb.service.ts<\/strong> file.<\/p>\n<p>Open the file and include the following TypeScript code:<\/p>\n<pre><code>import { Injectable, EventEmitter } from '@angular\/core';\r\nvar PouchDB = require(\"pouchdb\");\r\n\r\n@Injectable()\r\nexport class PouchDBService {\r\n\r\n    private isInstantiated: boolean;\r\n    private database: any;\r\n    private listener: EventEmitter = new EventEmitter();\r\n\r\n    public constructor() { }\r\n\r\n    public fetch() { }\r\n\r\n    public get(id: string) { }\r\n\r\n    public put(id: string, document: any) { }\r\n\r\n    public sync(remote: string) { }\r\n\r\n    public getChangeListener() { }\r\n\r\n}<\/code><\/pre>\n<p>Before we start filling in each of the methods, let&#8217;s figure out what we&#8217;re trying to do. We only want one database instance while the application is running. This can be accomplished via the <code>constructor<\/code> method:<\/p>\n<pre><code>public constructor() {\r\n    if(!this.isInstantiated) {\r\n        this.database = new PouchDB(\"nraboy\");\r\n        this.isInstantiated = true;\r\n    }\r\n}<\/code><\/pre>\n<p>In this case the local database is called <strong>nraboy<\/strong>. Now PouchDB does have a really great API. It just isn&#8217;t Angular 2 optimized, meaning working with PouchDB in its vanilla state in our project could have some hiccups.<\/p>\n<p>In the scenario where we want to fetch all local documents, we might do something like this:<\/p>\n<pre><code>public fetch() {\r\n    return this.database.allDocs({include_docs: true});\r\n}<\/code><\/pre>\n<p>We use the <code>include_docs<\/code> attribute so the documents get included in the results rather than just their id values. So maybe we only want to get a single document. We would do something like the following:<\/p>\n<pre><code>public get(id: string) {\r\n    return this.database.get(id);\r\n}<\/code><\/pre>\n<p>So far we have been using the PouchDB API exactly how the documentation recommends. How about changing it up a bit? The API offers a way to create or update documents, but let&#8217;s combine this in a single method?:<\/p>\n<pre><code>public put(id: string, document: any) {\r\n    document._id = id;\r\n    return this.get(id).then(result =&gt; {\r\n        document._rev = result._rev;\r\n        return this.database.put(document);\r\n    }, error =&gt; {\r\n        if(error.status == \"404\") {\r\n            return this.database.put(document);\r\n        } else {\r\n            return new Promise((resolve, reject) =&gt; {\r\n                reject(error);\r\n            });\r\n        }\r\n    });\r\n}<\/code><\/pre>\n<p>The above <code>put<\/code> method will check to see if a document exists based on its id. If it exists, copy the revision into the new data and save it again. If the document doesn&#8217;t exist, create it without a revision.<\/p>\n<p>You probably noticed the <code>EventEmitter<\/code> that was included near the top. This is necessary for subscribing to change events in the Angular 2 pages. Take the following <code>sync<\/code> method for example:<\/p>\n<pre><code>public sync(remote: string) {\r\n    let remoteDatabase = new PouchDB(remote);\r\n    this.database.sync(remoteDatabase, {\r\n        live: true\r\n    }).on('change', change =&gt; {\r\n        this.listener.emit(change);\r\n    });\r\n}<\/code><\/pre>\n<p>Here we are defining a remote data source, which will be Couchbase Sync Gateway, choosing to do a live two-way sync, and emitting the changes every time they are discovered.<\/p>\n<p>The change listener can be accessed on every page by accessing the following:<\/p>\n<pre><code>public getChangeListener() {\r\n    return this.listener;\r\n}<\/code><\/pre>\n<p>The the above we&#8217;d just end up subscribing to the listener.<\/p>\n<p>While the provider is created, it isn&#8217;t available across all pages yet. We need to import it into the project&#8217;s <code>@NgModule<\/code> found in the <strong>src\/app\/app.module.ts<\/strong> file. This file will look something like the following:<\/p>\n<pre><code>import { BrowserModule } from '@angular\/platform-browser';\r\nimport { NgModule } from '@angular\/core';\r\nimport { FormsModule } from '@angular\/forms';\r\nimport { HttpModule } from '@angular\/http';\r\n\r\nimport { AppComponent } from '.\/app.component';\r\nimport { PouchDBService } from \".\/pouchdb.service\";\r\n\r\n@NgModule({\r\n    declarations: [\r\n        AppComponent\r\n    ],\r\n    imports: [\r\n        BrowserModule,\r\n        FormsModule,\r\n        HttpModule\r\n    ],\r\n    providers: [PouchDBService],\r\n    bootstrap: [AppComponent]\r\n})\r\nexport class AppModule { }<\/code><\/pre>\n<p>Notice we&#8217;ve imported the provider class and added it to the <code>providers<\/code> array of the <code>@NgModule<\/code> block. Now we can use the provider throughout the application.<\/p>\n<h2 id=\"applying-the-database-provider-within-the-angular-2-application\">Applying the Database Provider within the Angular 2 Application<\/h2>\n<p>To keep things simple, this will be a single page application. We&#8217;re going to spend the rest of our time in the project&#8217;s <strong>src\/app\/app.component.ts<\/strong> and <strong>src\/app\/app.component.html<\/strong> files.<\/p>\n<p>Open the project&#8217;s <strong>src\/app\/app.component.ts<\/strong> file and include the following TypeScript code:<\/p>\n<pre><code>import { Component, OnInit, NgZone } from '@angular\/core';\r\nimport { PouchDBService } from \".\/pouchdb.service\";\r\n\r\n@Component({\r\n    selector: 'app-root',\r\n    templateUrl: '.\/app.component.html',\r\n    styleUrls: ['.\/app.component.css']\r\n})\r\nexport class AppComponent implements OnInit {\r\n\r\n    public people: Array;\r\n    public form: any;\r\n\r\n    public constructor(private database: PouchDBService, private zone: NgZone) {\r\n        this.people = [];\r\n        this.form = {\r\n            \"username\": \"\",\r\n            \"firstname\": \"\",\r\n            \"lastname\": \"\"\r\n        }\r\n    }\r\n\r\n    public ngOnInit() { }\r\n\r\n    public insert() { }\r\n\r\n}<\/code><\/pre>\n<p>You&#8217;ll notice that we&#8217;re importing the <code>PouchDBService<\/code> along with a few other things. We&#8217;ll explore those as we hit them.<\/p>\n<p>Inside the <code>AppComponent<\/code> we have a public array called <code>people<\/code> which will be bound to our UI. It will contain all the data being saved and synced. The <code>form<\/code> variable will represent an object containing each of our form elements. We could split it up into strings, but an object is more convenient because we&#8217;re going to end up saving the entire object as a document in Couchbase.<\/p>\n<p>In the <code>constructor<\/code> method we inject our PouchDB service and <code>NgZone<\/code>. We use <code>NgZone<\/code> to refresh the Angular 2 zone which sometimes gets bent out of shape when working with events and other kinds of listeners. Not too big a deal as you&#8217;ll see soon. Finally, the <code>constructor<\/code> method initializes our two variables.<\/p>\n<p>It is bad practice to load data in the <code>constructor<\/code> method so instead we use the <code>ngOnInit<\/code> method:<\/p>\n<pre><code>public ngOnInit() {\r\n    this.database.sync(\"https:\/\/localhost:4984\/example\");\r\n    this.database.getChangeListener().subscribe(data =&gt; {\r\n        for(let i = 0; i  {\r\n                this.people.push(data.change.docs[i]);\r\n            });\r\n        }\r\n    });\r\n    this.database.fetch().then(result =&gt; {\r\n        this.people = [];\r\n        for(let i = 0; i  {\r\n        console.error(error);\r\n    });\r\n}<\/code><\/pre>\n<p>Most of the application grunt work happens above. In the above code we are defining our remote Sync Gateway host and database name. It doesn&#8217;t need to match that of our local database. We then subscribe to our listener and loop through the changes as they come in. All changes are added to the public array within an <code>NgZone<\/code> so they refresh on the screen.<\/p>\n<p>Since change events only trigger as they happen, we need to fetch all the documents when we first initialize the application.<\/p>\n<p>This brings us to the <code>insert<\/code> method:<\/p>\n<pre><code>public insert() {\r\n    if(this.form.username &amp;&amp; this.form.firstname &amp;&amp; this.form.lastname) {\r\n        this.database.put(this.form.username, this.form);\r\n        this.form = {\r\n            \"username\": \"\",\r\n            \"firstname\": \"\",\r\n            \"lastname\": \"\"\r\n        }\r\n    }\r\n}<\/code><\/pre>\n<p>If our form elements are not blank then we can save the data as a document in the database. Once saved, the change event will trigger and the data will be added to the public array and displayed on the screen.<\/p>\n<p>This is all seamless between the web application and Couchbase Sync Gateway.<\/p>\n<h2 id=\"taking-it-for-a-test-drive\">Taking it for a Test Drive<\/h2>\n<p>There is a lot to take in when it comes to this Angular 2 and PouchDB guide. I <a href=\"https:\/\/github.com\/couchbaselabs\/pouchdb-angular2\">uploaded a working project<\/a> to GitHub if you&#8217;d like to take it for a spin.<\/p>\n<p>Download the project and execute the following from your Terminal or Command Prompt:<\/p>\n<pre><code>npm install<\/code><\/pre>\n<p>The above command will grab all the project dependencies. Make sure to update the <strong>src\/app\/app.component.ts<\/strong> file to reflect the correct hostname of your Sync Gateway and you should be good to go.<\/p>\n<p>The project can be executed by running:<\/p>\n<pre><code>ng serve<\/code><\/pre>\n<p>While serving, the project can be accessed from https:\/\/localhost:4200.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>You just saw how to build a simple web application that syncs data using PouchDB and <a href=\"https:\/\/www.couchbase.com\">Couchbase<\/a>. This is an Angular 2 application that is a step up from the <a href=\"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/\">guide I wrote last year<\/a> which used AngularJS 1.0.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last year I wrote an article that explained how to synchronize between platforms and Couchbase with only AngularJS and PouchDB. Back then AngularJS was booming and probably my favorite framework of all time. A year later AngularJS is still around, [&hellip;]<\/p>\n","protected":false},"author":63,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1815,1810,1816,9327],"tags":[1578,1543,1541,1718,1776],"ppma_author":[9032],"class_list":["post-2477","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-best-practices-and-tutorials","category-couchbase-mobile","category-couchbase-server","category-javascript","tag-angular-2","tag-javascript","tag-pouchdb","tag-typescript","tag-web-application"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB\" \/>\n<meta property=\"og:description\" content=\"Last year I wrote an article that explained how to synchronize between platforms and Couchbase with only AngularJS and PouchDB. Back then AngularJS was booming and probably my favorite framework of all time. A year later AngularJS is still around, [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/thepolyglotdeveloper\" \/>\n<meta property=\"article:published_time\" content=\"2017-01-05T15:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T03:15:35+00:00\" \/>\n<meta name=\"author\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@nraboy\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Nic Raboy, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB\",\"datePublished\":\"2017-01-05T15:00:00+00:00\",\"dateModified\":\"2025-06-14T03:15:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/\"},\"wordCount\":1539,\"commentCount\":3,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"angular 2\",\"javascript\",\"pouchdb\",\"TypeScript\",\"web application\"],\"articleSection\":[\"Best Practices and Tutorials\",\"Couchbase Mobile\",\"Couchbase Server\",\"JavaScript\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/\",\"name\":\"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2017-01-05T15:00:00+00:00\",\"dateModified\":\"2025-06-14T03:15:35+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1\",\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g\",\"caption\":\"Nic Raboy, Developer Advocate, Couchbase\"},\"description\":\"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.\",\"sameAs\":[\"https:\/\/www.thepolyglotdeveloper.com\",\"https:\/\/www.facebook.com\/thepolyglotdeveloper\",\"https:\/\/x.com\/nraboy\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/author\/nic-raboy-2\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/","og_locale":"en_US","og_type":"article","og_title":"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB","og_description":"Last year I wrote an article that explained how to synchronize between platforms and Couchbase with only AngularJS and PouchDB. Back then AngularJS was booming and probably my favorite framework of all time. A year later AngularJS is still around, [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2017-01-05T15:00:00+00:00","article_modified_time":"2025-06-14T03:15:35+00:00","author":"Nic Raboy, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@nraboy","twitter_misc":{"Written by":"Nic Raboy, Developer Advocate, Couchbase","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB","datePublished":"2017-01-05T15:00:00+00:00","dateModified":"2025-06-14T03:15:35+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/"},"wordCount":1539,"commentCount":3,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["angular 2","javascript","pouchdb","TypeScript","web application"],"articleSection":["Best Practices and Tutorials","Couchbase Mobile","Couchbase Server","JavaScript"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/","url":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/","name":"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2017-01-05T15:00:00+00:00","dateModified":"2025-06-14T03:15:35+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Using Couchbase Mobile in a Web Application with only Angular 2 and PouchDB"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"The Couchbase Blog","description":"Couchbase, the NoSQL Database","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"The Couchbase Blog","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1","name":"Nic Raboy, Developer Advocate, Couchbase","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/8863514d8bed0cf6080f23db40e00354","url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","caption":"Nic Raboy, Developer Advocate, Couchbase"},"description":"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/author\/nic-raboy-2\/"}]}},"authors":[{"term_id":9032,"user_id":63,"is_guest":0,"slug":"nic-raboy-2","display_name":"Nic Raboy, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g","author_category":"","last_name":"Raboy","first_name":"Nic","job_title":"","user_url":"https:\/\/www.thepolyglotdeveloper.com","description":"Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/comments?post=2477"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/posts\/2477\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/media?parent=2477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/categories?post=2477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/tags?post=2477"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/wp-json\/wp\/v2\/ppma_author?post=2477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}