{"id":2083,"date":"2015-09-30T18:22:47","date_gmt":"2015-09-30T18:22:46","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2083"},"modified":"2025-06-13T23:54:07","modified_gmt":"2025-06-14T06:54:07","slug":"sync-with-couchbase-using-only-angularjs-and-pouchdb","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/","title":{"rendered":"Sincronizaci\u00f3n con Couchbase usando s\u00f3lo AngularJS y PouchDB"},"content":{"rendered":"<p>There are many ways to use Couchbase in your web or mobile application through one of the various language SDKs. However, what if you were not using a backend language such as PHP or a mobile language such as Objective-C? What happens if you&#8217;re using a statically hosted web service such as Amazon S3 where you only have HTML, CSS, and JavaScript abilities?<\/p>\n<p>This is where PouchDB might come into play. <a href=\"https:\/\/pouchdb.com\/\">PouchDB<\/a> is a synchronization and storage library designed to work in a web browser using JavaScript. No backend code or SDKs are required to use this library with Couchbase. PouchDB can take the role of client side SDK and replicate the data to and from the Couchbase Sync Gateway. But PouchDB uses vanilla JavaScript, so what happens when your application uses AngularJS?<\/p>\n<p>We&#8217;re going to take a look at how to wrap various functions in PouchDB to make it more AngularJS friendly.<\/p>\n<h2>What We&#8217;ll Need<\/h2>\n<p>There are a few requirements to the application we&#8217;re going to build. We&#8217;ll see how to obtain them along the way, but here is a taste so you know what you&#8217;re getting yourself into.<\/p>\n<ul>\n<li>Python for running a simple HTTP server or something similar<\/li>\n<li>Couchbase Sync Gateway<\/li>\n<li>PouchDB 4<\/li>\n<li>AngularJS 1<\/li>\n<li>The AngularJS UI-Router library version 0.2<\/li>\n<li>Twitter Bootstrap 3<\/li>\n<\/ul>\n<h2>Laying The Foundation To Our Project<\/h2>\n<p>Before we get into the code, lets get our project structure situated and all libraries and styles into place.<\/p>\n<p>Somewhere on your computer create the directory <strong>PouchDB<\/strong> and add the following directories at the root:<\/p>\n<ul>\n<li>css<\/li>\n<li>fonts<\/li>\n<li>js<\/li>\n<li>templates<\/li>\n<\/ul>\n<p>At the root of your project you&#8217;ll also want to create a file called <strong>index.html<\/strong> and a file called <strong>sync-gateway-config.json<\/strong>.<\/p>\n<p>Now we need to download all the libraries for our project. Starting with <a href=\"https:\/\/getbootstrap.com\/\">Twitter Bootstrap<\/a>, download the latest and place all the <strong>min.css<\/strong> files into the <strong>css<\/strong> directory of your project, all the <strong>min.js<\/strong> files into the <strong>js<\/strong> directory of your project, and all the font files in the <strong>fonts<\/strong> directory of your project.<\/p>\n<p>With Twitter Bootstrap out of the way, next we need to download <a href=\"https:\/\/angularjs.org\/\">AngularJS<\/a> and the <a href=\"https:\/\/github.com\/angular-ui\/ui-router\">AngularJS UI-Router<\/a>. After downloading these libraries, place the <strong>min.js<\/strong> files into your project&#8217;s <strong>js<\/strong> directory.<\/p>\n<p>The last library to download is <a href=\"https:\/\/www.pouchdb.com\">PouchDB<\/a>. After downloading the <strong>min.js<\/strong> file, place it in the <strong>js<\/strong> directory of your project with all the rest.<\/p>\n<h3>Getting the Couchbase Sync Gateway<\/h3>\n<p>This project will require the Couchbase Sync Gateway in order to succeed. If you&#8217;re unfamiliar, the Couchbase Sync Gateway is a middleman service that handles processing data between the local application (your AngularJS application) and the Couchbase Server. We won&#8217;t be using Couchbase Server in this example so the Sync Gateway will act as our in-memory storage solution in the cloud.<\/p>\n<p>The Couchbase Sync Gateway can be found via the <a href=\"https:\/\/www.couchbase.com\/nosql-databases\/downloads\/\">Couchbase downloads section<\/a>.<\/p>\n<h2>Building Our Project<\/h2>\n<p>Now that all the files are in place we can start coding our application.<\/p>\n<h3>Including All The Scripts And Styles<\/h3>\n<p>Let&#8217;s start by including all styles and scripts into our <strong>index.html<\/strong> file. Open your <strong>index.html<\/strong> file and include the following code:<\/p>\n<pre><code class=\"language-xhtml\">\r\n<\/code><\/pre>\n<p>A few things to pay attention to in this <strong>index.html<\/strong> file. We&#8217;ve named our AngularJS application <strong>pouchapp<\/strong> and we are using a tag that might seem foreign:<\/p>\n<p>That tag is part of the AngularJS UI-Router. This is a single page application where each screen is a partial that loads into that tag. It will make more sense soon.<\/p>\n<h3>Creating The AngularJS Logic File<\/h3>\n<p>Inside your project&#8217;s <strong>js<\/strong> directory, create a file called <strong>app.js<\/strong> and include the following code:<\/p>\n<pre><code class=\"language-javascript\">\r\nangular.module(\"pouchapp\", [\"ui.router\"])\r\n\r\n.run(function($pouchDB) {\r\n\r\n})\r\n\r\n.config(function($stateProvider, $urlRouterProvider) {\r\n\r\n})\r\n\r\n.controller(\"MainController\", function($scope, $rootScope, $state, $stateParams, $pouchDB) {\r\n\r\n})\r\n<\/code><\/pre>\n<p>A few things to note about this file in general and what we&#8217;re going to do. The <strong>app.js<\/strong> file is where all our application logic will go. In it we have a <strong>.run()<\/strong> function that will be executed when the application launches, a <strong>.config()<\/strong> function that will configure all the screens in our application (UI-Router), and a <strong>.controller()<\/strong> function that will contain logic for the functionality of our particular application.<\/p>\n<p>Also take note of <strong>$pouchDB<\/strong> as this is an AngularJS service that we&#8217;ll design later.<\/p>\n<h4>The AngularJS Configuration<\/h4>\n<p>Since we&#8217;re using the AngularJS UI-Router we need to configure our routes in the <strong>.config()<\/strong> function of the <strong>app.js<\/strong> file. The code would look like the following:<\/p>\n<pre><code class=\"language-javascript\">\r\n$stateProvider\r\n    .state(\"list\", {\r\n        \"url\": \"\/list\",\r\n        \"templateUrl\": \"templates\/list.html\",\r\n        \"controller\": \"MainController\"\r\n    })\r\n    .state(\"item\", {\r\n        \"url\": \"\/item\/:documentId\/:documentRevision\",\r\n        \"templateUrl\": \"templates\/item.html\",\r\n        \"controller\": \"MainController\"\r\n    });\r\n$urlRouterProvider.otherwise(\"list\");\r\n<\/code><\/pre>\n<p>To sum it up, we have two routes (screens) here. We have a screen for showing a list of some sort and a screen that allows us to add or update items of the list. Both routes use an AngularJS controller called <strong>MainController<\/strong>, but each have a different template.<\/p>\n<h5>The AngularJS Route Templates<\/h5>\n<p>Each screen needs its own HTML to be shown to the user. In your project&#8217;s <strong>templates<\/strong> directory, create <strong>list.html<\/strong> and <strong>item.html<\/strong>. Open the <strong>list.html<\/strong> and add the following code:<\/p>\n<pre><code class=\"language-xhtml\"><button class=\"btn btn-primary\">New Item<\/button><\/code><\/pre>\n<p>&nbsp;<\/p>\n<table class=\"table table-striped\">\n<thead>\n<tr>\n<th>First Name<\/th>\n<th>Last Name<\/th>\n<th>Email<\/th>\n<th><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>{{value.firstname}}<\/td>\n<td>{{value.lastname}}<\/td>\n<td>{{value.email}}<\/td>\n<td><a>edit<\/a> | <a>delete<\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>A lot of this might look crazy, but I&#8217;ll explain it and it should make better sense. First off, we&#8217;re creating a table and looping through an object creating a new table row for each iteration. Being that this is an object we&#8217;re looping through, it will have both a key and a value which is why we have separated it. The value of this pair is also an object, which contains name information as well as email information.<\/p>\n<p>The line with the <strong>edit<\/strong> and <strong>delete<\/strong> is taking information from the object to either delete it from storage or pass it to a different screen so we can edit it.<\/p>\n<p>Now moving onto the second and last route for our application. Open the <strong>item.html<\/strong> file and include the following code:<\/p>\n<pre><code class=\"language-xhtml\"><\/code><\/pre>\n<p>&nbsp;<\/p>\n<div class=\"form-group\"><label for=\"firstname\">First Name<\/label> <\/div>\n<p>&nbsp;<\/p>\n<div class=\"form-group\"><label for=\"lastname\">Last Name<\/label> <\/div>\n<p>&nbsp;<\/p>\n<div class=\"form-group\"><label for=\"email\">Email<\/label> <\/div>\n<p><button class=\"btn btn-danger\" type=\"button\">Cancel<\/button> <button class=\"btn btn-success\" type=\"button\">Save<\/button><\/p>\n<p>Essentially this is just a form. We do have a save function in there that we&#8217;ll look at in the AngularJS controllers section coming next.<\/p>\n<h4>The PouchDB AngularJS Service<\/h4>\n<p>Before we go any further we need to talk about the AngularJS service for PouchDB. Otherwise, everything else is not going to make sense. We&#8217;re creating a service because we want things to be AngularJS friendly with PouchDB. We want to have reactive interfaces among other things. At the end of the <strong>app.js<\/strong> file, add the following code:<\/p>\n<pre><code class=\"language-javascript\">\r\n.service(\"$pouchDB\", [\"$rootScope\", \"$q\", function($rootScope, $q) {\r\n\r\n    var database;\r\n    var changeListener;\r\n\r\n    this.setDatabase = function(databaseName) {\r\n        database = new PouchDB(databaseName);\r\n    }\r\n\r\n    this.startListening = function() {\r\n        changeListener = database.changes({\r\n            live: true,\r\n            include_docs: true\r\n        }).on(\"change\", function(change) {\r\n            if(!change.deleted) {\r\n                $rootScope.$broadcast(\"$pouchDB:change\", change);\r\n            } else {\r\n                $rootScope.$broadcast(\"$pouchDB:delete\", change);\r\n            }\r\n        });\r\n    }\r\n\r\n    this.stopListening = function() {\r\n        changeListener.cancel();\r\n    }\r\n\r\n    this.sync = function(remoteDatabase) {\r\n        database.sync(remoteDatabase, {live: true, retry: true});\r\n    }\r\n\r\n    this.save = function(jsonDocument) {\r\n        var deferred = $q.defer();\r\n        if(!jsonDocument._id) {\r\n            database.post(jsonDocument).then(function(response) {\r\n                deferred.resolve(response);\r\n            }).catch(function(error) {\r\n                deferred.reject(error);\r\n            });\r\n        } else {\r\n            database.put(jsonDocument).then(function(response) {\r\n                deferred.resolve(response);\r\n            }).catch(function(error) {\r\n                deferred.reject(error);\r\n            });\r\n        }\r\n        return deferred.promise;\r\n    }\r\n\r\n    this.delete = function(documentId, documentRevision) {\r\n        return database.remove(documentId, documentRevision);\r\n    }\r\n\r\n    this.get = function(documentId) {\r\n        return database.get(documentId);\r\n    }\r\n\r\n    this.destroy = function() {\r\n        database.destroy();\r\n    }\r\n\r\n}]);\r\n<\/code><\/pre>\n<p>That is a lot to take in. We&#8217;re essentially just wrapping many of the PouchDB functions. However, what matters the most here is the <strong>startListening<\/strong> and <strong>save<\/strong> functions.<\/p>\n<p>Inside the <strong>startListening<\/strong> function we&#8217;re listening for changes and broadcasting them through the application using <strong>$rootScope.$broadcast<\/strong>. Although you haven&#8217;t seen it yet, AngularJS can pick up those broadcasts using <strong>$rootScope.$on<\/strong>. This makes changing the UI very easy.<\/p>\n<p>In terms of the <strong>save<\/strong> function, we are checking to see if a document id was passed to us. If no document id was passed it means that this is a new document to be inserted, otherwise it is an update.<\/p>\n<h4>Getting Back Into Our Controller And Run Function<\/h4>\n<p>Lets start with the AngularJS <strong>.run()<\/strong> function because it is short. Add the following code:<\/p>\n<pre><code class=\"language-javascript\">\r\n.run(function($pouchDB) {\r\n    $pouchDB.setDatabase(\"nraboy-test\");\r\n    $pouchDB.sync(\"https:\/\/localhost:4984\/test-database\");\r\n})\r\n<\/code><\/pre>\n<p>Here we name the local database and we tell it that we want to sync to this remote location which is actually our Couchbase Sync Gateway. This sync happens continuously after we call it. By continuously I mean changes will be replicated between application and server for as long as the application is open.<\/p>\n<p>Jumping into the controller code, add the following:<\/p>\n<pre><code class=\"language-javascript\">\r\n.controller(\"MainController\", function($scope, $rootScope, $state, $stateParams, $pouchDB) {\r\n\r\n    $scope.items = {};\r\n\r\n    $pouchDB.startListening();\r\n\r\n    $rootScope.$on(\"$pouchDB:change\", function(event, data) {\r\n        $scope.items[data.doc._id] = data.doc;\r\n        $scope.$apply();\r\n    });\r\n\r\n    $rootScope.$on(\"$pouchDB:delete\", function(event, data) {\r\n        delete $scope.items[data.doc._id];\r\n        $scope.$apply();\r\n    });\r\n\r\n    if($stateParams.documentId) {\r\n        $pouchDB.get($stateParams.documentId).then(function(result) {\r\n            $scope.inputForm = result;\r\n        });\r\n    }\r\n\r\n    $scope.save = function(firstname, lastname, email) {\r\n        var jsonDocument = {\r\n            \"firstname\": firstname,\r\n            \"lastname\": lastname,\r\n            \"email\": email\r\n        };\r\n        if($stateParams.documentId) {\r\n            jsonDocument[\"_id\"] = $stateParams.documentId;\r\n            jsonDocument[\"_rev\"] = $stateParams.documentRevision;\r\n        }\r\n        $pouchDB.save(jsonDocument).then(function(response) {\r\n            $state.go(\"list\");\r\n        }, function(error) {\r\n            console.log(\"ERROR -&gt; \" + error);\r\n        });\r\n    }\r\n\r\n    $scope.delete = function(id, rev) {\r\n        $pouchDB.delete(id, rev);\r\n    }\r\n\r\n})\r\n<\/code><\/pre>\n<p>The application is already syncing, so we need to listen for any changes. Here is the <strong>$rootScope.$on<\/strong> I mentioned earlier. We have two of them because in one we are listening for changes (create or update) and in the other we are listening for deletes.<\/p>\n<p>If the <strong>list.html<\/strong> page routed us here for an update, then we&#8217;ll have a document id passed. In this scenario we can do a lookup and get the data for that particular document id to display in the form rather than leaving it blank which is the default.<\/p>\n<p>Finally we have our <strong>save<\/strong> and <strong>delete<\/strong> functions.<\/p>\n<h2>The Sync Gateway Configuration<\/h2>\n<p>PouchDB and AngularJS is only half the story here. Sure they will create a nice locally running application, but we want things to sync. The Couchbase Sync Gateway is our endpoint for this and of course PouchDB works great with it.<\/p>\n<p>Inside your project&#8217;s <strong>sync-gateway-config.json<\/strong> file, add the following:<\/p>\n<pre><code class=\"language-json\">\r\n{\r\n    \"log\":[\"CRUD+\", \"REST+\", \"Changes+\", \"Attach+\"],\r\n    \"databases\": {\r\n        \"test-database\": {\r\n            \"server\":\"walrus:data\",\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:9000\"],\r\n        \"LoginOrigin\": [\"https:\/\/localhost:9000\"],\r\n        \"Headers\": [\"Content-Type\"],\r\n        \"MaxAge\": 17280000\r\n    }\r\n}\r\n<\/code><\/pre>\n<p>This is one of the most basic configurations around. A few things to note about it:<\/p>\n<ul>\n<li>It uses walrus:data for storage which is in memory and does not persist. Not to be used for production.<\/li>\n<li>All data is synced via the GUEST user, so there is no authentication happening here, but there could be<\/li>\n<li>We are fixing CORS issues by allowing requests on localhost:9000<\/li>\n<\/ul>\n<h2>Testing The Application<\/h2>\n<p>At this point all our code is in place and our Sync Gateway is ready to be run. Start up the Sync Gateway by running the following in a command prompt or terminal:<\/p>\n<pre><code class=\"language-bash\">\/path\/to\/sync\/gateway\/bin\/sync-gateway \/path\/to\/project\/sync-gateway-config.json<\/code><\/pre>\n<p>Now this is where Python comes into play. You cannot just open the HTML files in a web browser. They must be served to prevent CORS issues. From the command prompt or terminal, with the project as your current working directory, run the following:<\/p>\n<pre><code class=\"language-bash\">python -m SimpleHTTPServer 9000<\/code><\/pre>\n<p>Visit https:\/\/localhost:9000 in your web browser and check it out!<\/p>\n<h2>Conclusion<\/h2>\n<p>You now saw how to create a web application that can sync with Couchbase using nothing more than AngularJS and PouchDB. No backend SDKs were required.<\/p>\n<p>You can obtain the full working source code to this blog post via our <a href=\"https:\/\/github.com\/couchbaselabs\/pouchdb-angularjs-app\" target=\"_blank\" rel=\"noopener\">Couchbase Labs GitHub repository<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>There are many ways to use Couchbase in your web or mobile application through one of the various language SDKs. However, what if you were not using a backend language such as PHP or a mobile language such as Objective-C? [&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":[9327,2366],"tags":[1542,1543,1541],"ppma_author":[9032],"class_list":["post-2083","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript","category-sync-gateway","tag-angularjs","tag-javascript","tag-pouchdb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Sync With Couchbase Using Only AngularJS And PouchDB<\/title>\n<meta name=\"description\" content=\"Learn how to create a web application that can sync with Couchbase using nothing more than AngularJS and PouchDB. No backend SDKs were required.\" \/>\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\/es\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Sync With Couchbase Using Only AngularJS And PouchDB\" \/>\n<meta property=\"og:description\" content=\"Learn how to create a web application that can sync with Couchbase using nothing more than AngularJS and PouchDB. No backend SDKs were required.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/sync-with-couchbase-using-only-angularjs-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=\"2015-09-30T18:22:46+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T06:54:07+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=\"9 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/\"},\"author\":{\"name\":\"Nic Raboy, Developer Advocate, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/bb545ebe83bb2d12f91095811d0a72e1\"},\"headline\":\"Sync With Couchbase Using Only AngularJS And PouchDB\",\"datePublished\":\"2015-09-30T18:22:46+00:00\",\"dateModified\":\"2025-06-14T06:54:07+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/\"},\"wordCount\":1627,\"commentCount\":41,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"keywords\":[\"angularjs\",\"javascript\",\"pouchdb\"],\"articleSection\":[\"JavaScript\",\"Sync Gateway\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/\",\"name\":\"Sync With Couchbase Using Only AngularJS And PouchDB\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2015-09-30T18:22:46+00:00\",\"dateModified\":\"2025-06-14T06:54:07+00:00\",\"description\":\"Learn how to create a web application that can sync with Couchbase using nothing more than AngularJS and PouchDB. No backend SDKs were required.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/sync-with-couchbase-using-only-angularjs-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\\\/sync-with-couchbase-using-only-angularjs-and-pouchdb\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Sync With Couchbase Using Only AngularJS 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\":\"es\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@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\":\"es\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g8863514d8bed0cf6080f23db40e00354\",\"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\\\/es\\\/author\\\/nic-raboy-2\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Sincronizaci\u00f3n con Couchbase usando s\u00f3lo AngularJS y PouchDB","description":"Aprende a crear una aplicaci\u00f3n web que puede sincronizarse con Couchbase usando nada m\u00e1s que AngularJS y PouchDB. No se requieren SDKs de backend.","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\/es\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/","og_locale":"es_MX","og_type":"article","og_title":"Sync With Couchbase Using Only AngularJS And PouchDB","og_description":"Learn how to create a web application that can sync with Couchbase using nothing more than AngularJS and PouchDB. No backend SDKs were required.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/","og_site_name":"The Couchbase Blog","article_author":"https:\/\/www.facebook.com\/thepolyglotdeveloper","article_published_time":"2015-09-30T18:22:46+00:00","article_modified_time":"2025-06-14T06:54:07+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":"9 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/"},"author":{"name":"Nic Raboy, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/bb545ebe83bb2d12f91095811d0a72e1"},"headline":"Sync With Couchbase Using Only AngularJS And PouchDB","datePublished":"2015-09-30T18:22:46+00:00","dateModified":"2025-06-14T06:54:07+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/"},"wordCount":1627,"commentCount":41,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["angularjs","javascript","pouchdb"],"articleSection":["JavaScript","Sync Gateway"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/","url":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/","name":"Sincronizaci\u00f3n con Couchbase usando s\u00f3lo AngularJS y PouchDB","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2015-09-30T18:22:46+00:00","dateModified":"2025-06-14T06:54:07+00:00","description":"Aprende a crear una aplicaci\u00f3n web que puede sincronizarse con Couchbase usando nada m\u00e1s que AngularJS y PouchDB. No se requieren SDKs de backend.","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/sync-with-couchbase-using-only-angularjs-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\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Sync With Couchbase Using Only AngularJS And PouchDB"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"El blog de Couchbase","description":"Couchbase, la base de datos NoSQL","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":"es"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"El blog de Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"es","@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, Defensor del Desarrollador, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/secure.gravatar.com\/avatar\/bedeb68368d4681aca4c74fe5f697f0c423b80d498ec50fd915ba018b72c101f?s=96&d=mm&r=g8863514d8bed0cf6080f23db40e00354","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 es un defensor de las tecnolog\u00edas modernas de desarrollo web y m\u00f3vil. Tiene experiencia en Java, JavaScript, Golang y una variedad de frameworks como Angular, NativeScript y Apache Cordova. Nic escribe sobre sus experiencias de desarrollo relacionadas con hacer el desarrollo web y m\u00f3vil m\u00e1s f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/es\/author\/nic-raboy-2\/"}]}},"acf":[],"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","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2083","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=2083"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2083\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/media?parent=2083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2083"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}