{"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\/es\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/","title":{"rendered":"Usando Couchbase Mobile en una Aplicaci\u00f3n Web con solo Angular 2 y PouchDB"},"content":{"rendered":"<p>El a\u00f1o pasado escrib\u00ed un art\u00edculo en el que explicaba c\u00f3mo <a href=\"https:\/\/www.couchbase.com\/blog\/es\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/\">sincronizar entre plataformas y Couchbase con solo AngularJS y PouchDB<\/a>. Por aquel entonces AngularJS estaba en auge y probablemente era mi framework favorito de todos los tiempos. Un a\u00f1o despu\u00e9s, AngularJS sigue existiendo, pero poco a poco est\u00e1 siendo reemplazado por Angular 2, la pr\u00f3xima versi\u00f3n del popular framework. Despu\u00e9s de usar Angular 2, miro hacia atr\u00e1s a AngularJS 1.0 y me pregunto qu\u00e9 estaba pasando por mi cerebro porque Angular 2 es pura genialidad.<\/p>\n<p>En esta ocasi\u00f3n vamos a ver c\u00f3mo crear una aplicaci\u00f3n web sencilla que se sincroniza usando \u00fanicamente Angular 2, PouchDB y Couchbase Mobile.<\/p>\n<h2 id=\"the-requirements\">Requisitos<\/h2>\n<p>Los pocos requisitos para tener \u00e9xito con este proyecto son los siguientes:<\/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\">Tipolog\u00edas<\/a><\/li>\n<li>Pasarela de sincronizaci\u00f3n Couchbase<\/li>\n<\/ul>\n<p>La CLI de Angular 2 se puede instalar utilizando el Node Package Manager (NPM) que se incluye con Node.js. NPM tambi\u00e9n se utiliza cuando se trata de reunir varias dependencias del proyecto. No vamos a usar Couchbase Server en este ejemplo, pero podr\u00edamos. En su lugar s\u00f3lo vamos a utilizar Couchbase Sync Gateway y sus caracter\u00edsticas de prototipado.<\/p>\n<h2 id=\"configuring-couchbase-sync-gateway\">Configuraci\u00f3n de Couchbase Sync Gateway<\/h2>\n<p>Couchbase Sync Gateway es necesario para manejar toda la sincronizaci\u00f3n. Sin \u00e9l s\u00f3lo tenemos almacenamiento local en nuestra aplicaci\u00f3n web, y con toda honestidad, hay soluciones mucho mejores que PouchDB si s\u00f3lo quisieras almacenamiento local.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/es\/nosql-databases\/downloads\/\">Descargar<\/a> la \u00faltima Sync Gateway e implem\u00e9ntala con la siguiente configuraci\u00f3n:<\/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>Gu\u00e1rdelo en un archivo llamado <strong>sync-gateway-config.json<\/strong> si lo desea. Esta es una configuraci\u00f3n muy b\u00e1sica en la que estamos utilizando un <a href=\"https:\/\/www.couchbase.com\/blog\/es\/resources\/concepts\/in-memory-database\/\">base de datos en memoria<\/a> llamado <strong>ejemplo<\/strong>. No hay permisos de lectura y escritura as\u00ed que todo vale. En la parte inferior de esta configuraci\u00f3n tenemos algunos elementos relacionados con la compartici\u00f3n de recursos entre or\u00edgenes (CORS). Debido a que estaremos sirviendo nuestra aplicaci\u00f3n localmente, necesitamos identificar esto para prevenir errores de JavaScript.<\/p>\n<h2 id=\"creating-a-new-angular-2-project\">Creaci\u00f3n de un nuevo proyecto Angular 2<\/h2>\n<p>Para hacer las cosas f\u00e1ciles de entender vamos a crear un proyecto con un dise\u00f1o incre\u00edblemente simplista. Vamos a crear una sencilla aplicaci\u00f3n de gesti\u00f3n de usuarios donde podremos a\u00f1adir personas y se sincronizar\u00e1n donde queramos. Por ejemplo, mira la animaci\u00f3n de abajo:<\/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>En la animaci\u00f3n anterior tenemos dos navegadores web. A\u00f1ade una persona a uno y se sincronizar\u00e1 con el otro. Esto es algo que ser\u00eda particularmente dif\u00edcil sin Couchbase.<\/p>\n<p>Empecemos creando un nuevo proyecto Angular 2 usando el Angular CLI. Ejecute lo siguiente desde su s\u00edmbolo del sistema (Windows) o Terminal (Mac y Linux):<\/p>\n<pre><code>ng nuevo PouchDBProject<\/code><\/pre>\n<p>Puede tardar un poco, pero cuando se cree el proyecto queremos instalar PouchDB y cualquier dependencia necesaria. Ejecuta lo siguiente para instalar la \u00faltima versi\u00f3n de PouchDB:<\/p>\n<pre><code>npm install pouchdb --save<\/code><\/pre>\n<p>Los mantenedores de PouchDB tienen sentimientos encontrados cuando se trata de TypeScript, una tecnolog\u00eda cr\u00edtica cuando se trata del desarrollo de Angular 2. Por esta raz\u00f3n no hay definiciones de tipos fiables disponibles. Sin embargo, esto no es un gran problema.<\/p>\n<p>Usando Typings, vamos a instalar lo siguiente:<\/p>\n<pre><code>typings install dt~require --save --global<\/code><\/pre>\n<p>Las definiciones de tipo anteriores nos permitir\u00e1n utilizar la funci\u00f3n <code>requiere<\/code> dentro de TypeScript. Con ella podemos importar el PouchDB descargado a nuestro proyecto.<\/p>\n<p>Llegados a este punto, \u00a1ya podemos empezar a desarrollar nuestro proyecto!<\/p>\n<h2 id=\"developing-an-angular-2-provider-to-maintain-the-data\">Desarrollo de un proveedor Angular 2 para mantener los datos<\/h2>\n<p>Cuando se trabaja con datos siempre es una buena idea crear un servicio Angular 2, tambi\u00e9n conocido como proveedor. Esto nos permite tener una instancia singleton y una clase segregada del resto de nuestro c\u00f3digo. Es genial desde una perspectiva de mantenibilidad.<\/p>\n<p>Puede crear el proveedor manualmente o utilizando la CLI. Desde la CLI, ejecute lo siguiente:<\/p>\n<pre><code>ng g service pouchdb<\/code><\/pre>\n<p>Deben crearse dos archivos en el directorio del proyecto <strong>src\/app<\/strong> directorio. Deber\u00eda tener un <strong>pouchdb.service.ts<\/strong> y un <strong>pouchdb.service.spec.ts<\/strong> archivo. Pueden tener un nombre similar, pero el nombre no es realmente importante.<\/p>\n<p>En <strong>spec<\/strong> es un archivo de pruebas unitarias, algo de lo que no nos preocuparemos en este ejemplo en particular. En su lugar vamos a empezar a desarrollar en el <strong>pouchdb.service.ts<\/strong> archivo.<\/p>\n<p>Abra el archivo e incluya el siguiente c\u00f3digo TypeScript:<\/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>Antes de empezar a rellenar cada uno de los m\u00e9todos, vamos a averiguar lo que estamos tratando de hacer. S\u00f3lo queremos una instancia de base de datos mientras se ejecuta la aplicaci\u00f3n. Esto se puede lograr mediante el m\u00e9todo <code>constructor<\/code> m\u00e9todo:<\/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>En este caso, la base de datos local se llama <strong>nraboy<\/strong>. PouchDB tiene una API realmente buena. S\u00f3lo que no est\u00e1 optimizada para Angular 2, lo que significa que trabajar con PouchDB en su estado vainilla en nuestro proyecto podr\u00eda tener algunos contratiempos.<\/p>\n<p>En el caso de que queramos recuperar todos los documentos locales, podr\u00edamos hacer algo as\u00ed:<\/p>\n<pre><code>public fetch() {\r\n    return this.database.allDocs({include_docs: true});\r\n}<\/code><\/pre>\n<p>Utilizamos el <code>incluir_docs<\/code> para que los documentos se incluyan en los resultados y no s\u00f3lo sus valores de id. Tal vez s\u00f3lo queramos obtener un \u00fanico documento. Har\u00edamos algo como lo siguiente<\/p>\n<pre><code>public get(id: cadena) {\r\n    return this.database.get(id);\r\n}<\/code><\/pre>\n<p>Hasta ahora hemos estado utilizando la API de PouchDB exactamente como recomienda la documentaci\u00f3n. \u00bfQu\u00e9 tal si lo cambiamos un poco? La API ofrece una manera de crear o actualizar documentos, pero vamos a combinar esto en un solo m\u00e9todo?:<\/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>Lo anterior <code>poner<\/code> comprobar\u00e1 si existe un documento bas\u00e1ndose en su id. Si existe, copia la revisi\u00f3n en los nuevos datos y lo guarda de nuevo. Si el documento no existe, lo crear\u00e1 sin revisi\u00f3n.<\/p>\n<p>Seguramente se habr\u00e1 dado cuenta de que <code>Emisor de eventos<\/code> que se incluy\u00f3 cerca de la parte superior. Esto es necesario para suscribirse a eventos de cambio en las p\u00e1ginas de Angular 2. Tome el siguiente <code>sincronizar<\/code> por ejemplo:<\/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>Aqu\u00ed estamos definiendo una fuente de datos remota, que ser\u00e1 Couchbase Sync Gateway, eligiendo hacer una sincronizaci\u00f3n bidireccional en vivo, y emitiendo los cambios cada vez que son descubiertos.<\/p>\n<p>Se puede acceder al escuchador de cambios en cada p\u00e1gina accediendo a lo siguiente:<\/p>\n<pre><code>public getChangeListener() {\r\n    return this.listener;\r\n}<\/code><\/pre>\n<p>Con lo anterior acabar\u00edamos suscribi\u00e9ndonos al oyente.<\/p>\n<p>Aunque el proveedor est\u00e1 creado, a\u00fan no est\u00e1 disponible en todas las p\u00e1ginas. Tenemos que importarlo en el proyecto de <code>@NgModule<\/code> que se encuentra en el <strong>src\/app\/app.module.ts<\/strong> archivo. Este archivo tendr\u00e1 un aspecto similar al siguiente<\/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>F\u00edjate en que hemos importado la clase provider y la hemos a\u00f1adido a la clase <code>proveedores<\/code> de la <code>@NgModule<\/code> bloque. Ahora podemos utilizar el proveedor en toda la aplicaci\u00f3n.<\/p>\n<h2 id=\"applying-the-database-provider-within-the-angular-2-application\">Aplicando el Proveedor de Base de Datos dentro de la Aplicaci\u00f3n Angular 2<\/h2>\n<p>Para mantener las cosas simples, esta ser\u00e1 una aplicaci\u00f3n de una sola p\u00e1gina. Vamos a pasar el resto de nuestro tiempo en el proyecto de <strong>src\/app\/app.component.ts<\/strong> y <strong>src\/app\/app.component.html<\/strong> archivos.<\/p>\n<p>Abra el archivo <strong>src\/app\/app.component.ts<\/strong> e incluya el siguiente c\u00f3digo TypeScript:<\/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>Ver\u00e1s que estamos importando el archivo <code>PouchDBService<\/code> junto con algunas otras cosas. Las analizaremos a medida que las vayamos encontrando.<\/p>\n<p>Dentro de la <code>AppComponent<\/code> tenemos un array p\u00fablico llamado <code>gente<\/code> que se vincular\u00e1 a nuestra interfaz de usuario. Contendr\u00e1 todos los datos que se guarden y sincronicen. La p\u00e1gina <code>formulario<\/code> representar\u00e1 un objeto que contiene cada uno de los elementos de nuestro formulario. Podr\u00edamos dividirlo en cadenas, pero un objeto es m\u00e1s conveniente porque vamos a terminar guardando todo el objeto como un documento en Couchbase.<\/p>\n<p>En el <code>constructor<\/code> inyectamos nuestro servicio PouchDB y <code>NgZone<\/code>. Utilizamos <code>NgZone<\/code> para refrescar la zona de Angular 2 que a veces se l\u00eda parda cuando se trabaja con eventos y otro tipo de listeners. No es gran cosa como ver\u00e1s pronto. Por \u00faltimo, el <code>constructor<\/code> inicializa nuestras dos variables.<\/p>\n<p>Es una mala pr\u00e1ctica cargar datos en el <code>constructor<\/code> por lo que en su lugar utilizaremos el m\u00e9todo <code>ngOnInit<\/code> m\u00e9todo:<\/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>La mayor parte de la aplicaci\u00f3n grunt trabajo sucede por encima. En el c\u00f3digo anterior estamos definiendo nuestro host remoto Sync Gateway y el nombre de la base de datos. No es necesario que coincida con la de nuestra base de datos local. A continuaci\u00f3n, suscribirse a nuestro oyente y el bucle a trav\u00e9s de los cambios a medida que llegan. Todos los cambios se a\u00f1aden a la matriz p\u00fablica dentro de un <code>NgZone<\/code> para que se refresquen en la pantalla.<\/p>\n<p>Dado que los eventos de cambio s\u00f3lo se activan cuando se producen, necesitamos obtener todos los documentos cuando inicializamos la aplicaci\u00f3n por primera vez.<\/p>\n<p>Esto nos lleva a la <code>insertar<\/code> m\u00e9todo:<\/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>Si los elementos de nuestro formulario no est\u00e1n en blanco, podemos guardar los datos como un documento en la base de datos. Una vez guardados, el evento de cambio se disparar\u00e1 y los datos se a\u00f1adir\u00e1n al array p\u00fablico y se mostrar\u00e1n en pantalla.<\/p>\n<p>Todo esto es perfecto entre la aplicaci\u00f3n web y Couchbase Sync Gateway.<\/p>\n<h2 id=\"taking-it-for-a-test-drive\">Prueba de conducci\u00f3n<\/h2>\n<p>Hay mucho que asimilar cuando se trata de esta gu\u00eda de Angular 2 y PouchDB. I <a href=\"https:\/\/github.com\/couchbaselabs\/pouchdb-angular2\">cargado un proyecto de trabajo<\/a> en GitHub si quieres probarlo.<\/p>\n<p>Descargue el proyecto y ejecute lo siguiente desde su Terminal o S\u00edmbolo del sistema:<\/p>\n<pre><code>npm instalar<\/code><\/pre>\n<p>El comando anterior obtendr\u00e1 todas las dependencias del proyecto. Aseg\u00farese de actualizar el <strong>src\/app\/app.component.ts<\/strong> para que refleje el nombre de host correcto de su Sync Gateway y ya puede empezar.<\/p>\n<p>El proyecto puede ejecutarse ejecutando:<\/p>\n<pre><code>ng serve<\/code><\/pre>\n<p>Mientras sirve, se puede acceder al proyecto desde https:\/\/localhost:4200.<\/p>\n<h2 id=\"conclusion\">Conclusi\u00f3n<\/h2>\n<p>Acabas de ver c\u00f3mo construir una sencilla aplicaci\u00f3n web que sincroniza datos usando PouchDB y <a href=\"https:\/\/www.couchbase.com\/blog\/es\/\">Couchbase<\/a>. Esta es una aplicaci\u00f3n Angular 2 que es un paso adelante de la <a href=\"https:\/\/www.couchbase.com\/blog\/es\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/\">gu\u00eda que escrib\u00ed el a\u00f1o pasado<\/a> que utilizaba AngularJS 1.0.<\/p>","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>","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 v26.1 (Yoast SEO v26.1.1) - 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\/es\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\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\/es\/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 minutos\" \/>\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\":\"es\",\"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\":\"es\",\"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\":\"es\",\"@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\":\"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:\/\/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\/es\/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\/es\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/","og_locale":"es_MX","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\/es\/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 minutos"},"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":"es","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":"es","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":"es","@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":"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:\/\/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 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\/"}]}},"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 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."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2477","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=2477"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/2477\/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=2477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=2477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=2477"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=2477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}