{"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\/pt\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/","title":{"rendered":"Uso do Couchbase Mobile em um aplicativo da Web com apenas Angular 2 e PouchDB"},"content":{"rendered":"<p>No ano passado, escrevi um artigo que explicava como <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/\">sincronizar entre plataformas e o Couchbase apenas com AngularJS e PouchDB<\/a>. Naquela \u00e9poca, o AngularJS estava em alta e provavelmente era minha estrutura favorita de todos os tempos. Um ano depois, o AngularJS ainda existe, mas est\u00e1 sendo lentamente substitu\u00eddo pelo Angular 2, a pr\u00f3xima vers\u00e3o da popular estrutura. Depois de usar o Angular 2, olho para o AngularJS 1.0 e me pergunto o que estava passando pela minha cabe\u00e7a, porque o Angular 2 \u00e9 pura maravilha.<\/p>\n<p>Desta vez, veremos como criar um aplicativo da Web simples que sincroniza usando apenas o Angular 2, o PouchDB e o Couchbase Mobile.<\/p>\n<h2 id=\"the-requirements\">Os requisitos<\/h2>\n<p>Os poucos requisitos para ter sucesso com esse projeto s\u00e3o os seguintes:<\/p>\n<ul>\n<li>Node.js 4.0+<\/li>\n<li>CLI do Angular 2<\/li>\n<li><a href=\"https:\/\/github.com\/typings\/typings\">Tipifica\u00e7\u00f5es<\/a><\/li>\n<li>Gateway de sincroniza\u00e7\u00e3o do Couchbase<\/li>\n<\/ul>\n<p>A CLI do Angular 2 pode ser instalada usando o NPM (Node Package Manager), que est\u00e1 inclu\u00eddo no Node.js. O NPM tamb\u00e9m \u00e9 usado quando se trata de reunir v\u00e1rias depend\u00eancias de projeto. N\u00e3o usaremos o Couchbase Server neste exemplo, mas poder\u00edamos. Em vez disso, usaremos apenas o Couchbase Sync Gateway e seus recursos de prototipagem.<\/p>\n<h2 id=\"configuring-couchbase-sync-gateway\">Configura\u00e7\u00e3o do Couchbase Sync Gateway<\/h2>\n<p>O Couchbase Sync Gateway \u00e9 necess\u00e1rio para lidar com toda a sincroniza\u00e7\u00e3o. Sem ele, temos apenas armazenamento local em nosso aplicativo Web e, honestamente, h\u00e1 solu\u00e7\u00f5es muito melhores do que o PouchDB se voc\u00ea quiser apenas armazenamento local.<\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/pt\/nosql-databases\/downloads\/\">Baixar<\/a> o Sync Gateway mais recente e implemente-o com a seguinte configura\u00e7\u00e3o:<\/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>Salve isso em um arquivo chamado <strong>sync-gateway-config.json<\/strong> se voc\u00ea quiser. Esta \u00e9 uma configura\u00e7\u00e3o muito b\u00e1sica em que estamos usando um <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/resources\/concepts\/in-memory-database\/\">banco de dados na mem\u00f3ria<\/a> chamado <strong>exemplo<\/strong>. N\u00e3o h\u00e1 permiss\u00f5es de leitura e grava\u00e7\u00e3o, portanto, vale tudo. Na parte inferior dessa configura\u00e7\u00e3o, temos alguns itens relacionados ao compartilhamento de recursos entre origens (CORS). Como estaremos servindo nosso aplicativo localmente, precisamos identificar isso para evitar erros de JavaScript.<\/p>\n<h2 id=\"creating-a-new-angular-2-project\">Criando um novo projeto Angular 2<\/h2>\n<p>Para facilitar a compreens\u00e3o, vamos criar um projeto com um design incrivelmente simples. Vamos criar um aplicativo simples de gerenciamento de usu\u00e1rios, no qual podemos adicionar pessoas e elas ser\u00e3o sincronizadas para onde voc\u00ea quiser. Por exemplo, veja a anima\u00e7\u00e3o abaixo:<\/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>Na anima\u00e7\u00e3o acima, temos dois navegadores da Web. Adicione uma pessoa a um deles e ela ser\u00e1 sincronizada com o outro. Isso \u00e9 algo que seria particularmente dif\u00edcil sem o Couchbase.<\/p>\n<p>Vamos come\u00e7ar criando um novo projeto do Angular 2 usando a CLI do Angular. Execute o seguinte em seu prompt de comando (Windows) ou terminal (Mac e Linux):<\/p>\n<pre><code>ng new PouchDBProject<\/code><\/pre>\n<p>Pode demorar um pouco, mas quando o projeto for criado, queremos instalar o PouchDB e todas as depend\u00eancias necess\u00e1rias. Execute o seguinte para instalar o PouchDB mais recente:<\/p>\n<pre><code>npm install pouchdb --save<\/code><\/pre>\n<p>Os mantenedores do PouchDB t\u00eam emo\u00e7\u00f5es contradit\u00f3rias quando se trata de TypeScript, uma tecnologia essencial para o desenvolvimento do Angular 2. Por esse motivo, n\u00e3o h\u00e1 defini\u00e7\u00f5es de tipo confi\u00e1veis dispon\u00edveis. No entanto, isso n\u00e3o \u00e9 um grande problema.<\/p>\n<p>Usando o Typings, vamos instalar o seguinte:<\/p>\n<pre><code>typings install dt~require --save --global<\/code><\/pre>\n<p>As defini\u00e7\u00f5es de tipo acima nos permitir\u00e3o usar o <code>exigir<\/code> no TypeScript. Com ela, podemos importar o PouchDB baixado para o nosso projeto.<\/p>\n<p>Nesse ponto, podemos come\u00e7ar a desenvolver nosso projeto!<\/p>\n<h2 id=\"developing-an-angular-2-provider-to-maintain-the-data\">Desenvolvimento de um provedor Angular 2 para manter os dados<\/h2>\n<p>Ao trabalhar com dados, \u00e9 sempre uma boa ideia criar um servi\u00e7o do Angular 2, tamb\u00e9m conhecido como provedor. Isso nos permite ter uma inst\u00e2ncia singleton e uma classe separada do restante do nosso c\u00f3digo. Isso \u00e9 \u00f3timo do ponto de vista da manuten\u00e7\u00e3o.<\/p>\n<p>Voc\u00ea pode criar o provedor manualmente ou usando a CLI. Na CLI, execute o seguinte:<\/p>\n<pre><code>ng g service pouchdb<\/code><\/pre>\n<p>Dois arquivos devem ser criados no diret\u00f3rio <strong>src\/app<\/strong> diret\u00f3rio. Voc\u00ea deve ter um diret\u00f3rio <strong>pouchdb.service.ts<\/strong> e um <strong>pouchdb.service.spec.ts<\/strong> arquivo. Eles podem ter um nome semelhante, mas o nome n\u00e3o \u00e9 realmente importante.<\/p>\n<p>O <strong>especifica\u00e7\u00e3o<\/strong> \u00e9 um arquivo de teste de unidade, algo com que n\u00e3o nos preocuparemos neste exemplo espec\u00edfico. Em vez disso, vamos come\u00e7ar a desenvolver no arquivo <strong>pouchdb.service.ts<\/strong> arquivo.<\/p>\n<p>Abra o arquivo e inclua o seguinte 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 come\u00e7armos a preencher cada um dos m\u00e9todos, vamos descobrir o que estamos tentando fazer. Queremos apenas uma inst\u00e2ncia de banco de dados enquanto o aplicativo estiver em execu\u00e7\u00e3o. Isso pode ser feito por meio do m\u00e9todo <code>construtor<\/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>Nesse caso, o banco de dados local \u00e9 chamado de <strong>garoto<\/strong>. Agora, o PouchDB tem uma API realmente excelente. Ela s\u00f3 n\u00e3o \u00e9 otimizada para o Angular 2, o que significa que trabalhar com o PouchDB em seu estado original em nosso projeto pode ter alguns problemas.<\/p>\n<p>No cen\u00e1rio em que queremos buscar todos os documentos locais, podemos fazer algo assim:<\/p>\n<pre><code>public fetch() {\r\n    return this.database.allDocs({include_docs: true});\r\n}<\/code><\/pre>\n<p>Usamos o <code>incluir_docs<\/code> para que os documentos sejam inclu\u00eddos nos resultados em vez de apenas seus valores de id. Ent\u00e3o, talvez queiramos obter apenas um \u00fanico documento. Far\u00edamos algo como o seguinte:<\/p>\n<pre><code>public get(id: string) {\r\n    return this.database.get(id);\r\n}<\/code><\/pre>\n<p>At\u00e9 agora, usamos a API do PouchDB exatamente como a documenta\u00e7\u00e3o recomenda. Que tal mudar um pouco? A API oferece uma maneira de criar ou atualizar documentos, mas vamos combinar isso em um \u00fanico 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>O acima <code>colocar<\/code> verificar\u00e1 se um documento existe com base em seu ID. Se existir, copie a revis\u00e3o para os novos dados e salve-a novamente. Se o documento n\u00e3o existir, crie-o sem uma revis\u00e3o.<\/p>\n<p>Voc\u00ea provavelmente notou o <code>Emissor de eventos<\/code> que foi inclu\u00eddo pr\u00f3ximo ao topo. Isso \u00e9 necess\u00e1rio para a assinatura de eventos de altera\u00e7\u00e3o nas p\u00e1ginas do Angular 2. Veja o seguinte <code>sincroniza\u00e7\u00e3o<\/code> por exemplo:<\/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>Aqui estamos definindo uma fonte de dados remota, que ser\u00e1 o Couchbase Sync Gateway, optando por fazer uma sincroniza\u00e7\u00e3o bidirecional em tempo real e emitindo as altera\u00e7\u00f5es sempre que elas forem descobertas.<\/p>\n<p>O ouvinte de altera\u00e7\u00f5es pode ser acessado em todas as p\u00e1ginas, acessando o seguinte:<\/p>\n<pre><code>public getChangeListener() {\r\n    return this.listener;\r\n}<\/code><\/pre>\n<p>Com isso, acabar\u00edamos assinando o ouvinte.<\/p>\n<p>Embora o provedor tenha sido criado, ele ainda n\u00e3o est\u00e1 dispon\u00edvel em todas as p\u00e1ginas. Precisamos import\u00e1-lo para a se\u00e7\u00e3o <code>@NgModule<\/code> encontrado no <strong>src\/app\/app.module.ts<\/strong> arquivo. Esse arquivo ser\u00e1 parecido com o seguinte:<\/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>Observe que importamos a classe do provedor e a adicionamos \u00e0 classe <code>provedores<\/code> matriz do <code>@NgModule<\/code> bloco. Agora podemos usar o provedor em todo o aplicativo.<\/p>\n<h2 id=\"applying-the-database-provider-within-the-angular-2-application\">Aplica\u00e7\u00e3o do provedor de banco de dados no aplicativo Angular 2<\/h2>\n<p>Para manter as coisas simples, este ser\u00e1 um aplicativo de p\u00e1gina \u00fanica. Passaremos o resto de nosso tempo na se\u00e7\u00e3o <strong>src\/app\/app.component.ts<\/strong> e <strong>src\/app\/app.component.html<\/strong> arquivos.<\/p>\n<p>Abra o arquivo <strong>src\/app\/app.component.ts<\/strong> e inclua o seguinte 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>Voc\u00ea notar\u00e1 que estamos importando o <code>Servi\u00e7o PouchDBService<\/code> al\u00e9m de alguns outros aspectos. Vamos explor\u00e1-los \u00e0 medida que os encontrarmos.<\/p>\n<p>Dentro do <code>Componente de aplicativo<\/code> temos uma matriz p\u00fablica chamada <code>pessoas<\/code> que ser\u00e1 vinculado \u00e0 nossa interface do usu\u00e1rio. Ele conter\u00e1 todos os dados que est\u00e3o sendo salvos e sincronizados. O <code>formul\u00e1rio<\/code> representar\u00e1 um objeto que cont\u00e9m cada um dos nossos elementos de formul\u00e1rio. Poder\u00edamos dividi-lo em cadeias de caracteres, mas um objeto \u00e9 mais conveniente porque acabaremos salvando o objeto inteiro como um documento no Couchbase.<\/p>\n<p>No <code>construtor<\/code> injetamos nosso servi\u00e7o PouchDB e o m\u00e9todo <code>NgZone<\/code>. Usamos <code>NgZone<\/code> para atualizar a zona do Angular 2, que, \u00e0s vezes, fica fora de forma ao trabalhar com eventos e outros tipos de ouvintes. N\u00e3o \u00e9 um problema muito grande, como voc\u00ea ver\u00e1 em breve. Por fim, a se\u00e7\u00e3o <code>construtor<\/code> inicializa nossas duas vari\u00e1veis.<\/p>\n<p>\u00c9 uma pr\u00e1tica ruim carregar dados no <code>construtor<\/code> portanto, em vez disso, usamos o 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>A maior parte do trabalho do aplicativo grunt acontece acima. No c\u00f3digo acima, estamos definindo o host remoto do Sync Gateway e o nome do banco de dados. Ele n\u00e3o precisa ser igual ao do nosso banco de dados local. Em seguida, nos inscrevemos em nosso ouvinte e percorremos as altera\u00e7\u00f5es \u00e0 medida que elas chegam. Todas as altera\u00e7\u00f5es s\u00e3o adicionadas \u00e0 matriz p\u00fablica dentro de um <code>NgZone<\/code> para que sejam atualizados na tela.<\/p>\n<p>Como os eventos de altera\u00e7\u00e3o s\u00e3o acionados apenas quando ocorrem, precisamos buscar todos os documentos quando inicializamos o aplicativo pela primeira vez.<\/p>\n<p>Isso nos leva ao <code>inserir<\/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>Se os elementos do formul\u00e1rio n\u00e3o estiverem em branco, poderemos salvar os dados como um documento no banco de dados. Depois de salvos, o evento de altera\u00e7\u00e3o ser\u00e1 acionado e os dados ser\u00e3o adicionados \u00e0 matriz p\u00fablica e exibidos na tela.<\/p>\n<p>Tudo isso \u00e9 feito sem interrup\u00e7\u00f5es entre o aplicativo da Web e o Couchbase Sync Gateway.<\/p>\n<h2 id=\"taking-it-for-a-test-drive\">Levando-o para um test drive<\/h2>\n<p>H\u00e1 muito o que aprender neste guia sobre o Angular 2 e o PouchDB. I <a href=\"https:\/\/github.com\/couchbaselabs\/pouchdb-angular2\">fez o upload de um projeto funcional<\/a> para o GitHub se voc\u00ea quiser dar uma olhada nele.<\/p>\n<p>Fa\u00e7a o download do projeto e execute o seguinte em seu Terminal ou Prompt de Comando:<\/p>\n<pre><code>npm install<\/code><\/pre>\n<p>O comando acima obter\u00e1 todas as depend\u00eancias do projeto. Certifique-se de atualizar o <strong>src\/app\/app.component.ts<\/strong> para refletir o nome de host correto do Sync Gateway e voc\u00ea estar\u00e1 pronto para come\u00e7ar.<\/p>\n<p>O projeto pode ser executado com a execu\u00e7\u00e3o:<\/p>\n<pre><code>ng serve<\/code><\/pre>\n<p>Enquanto estiver em funcionamento, o projeto pode ser acessado em https:\/\/localhost:4200.<\/p>\n<h2 id=\"conclusion\">Conclus\u00e3o<\/h2>\n<p>Voc\u00ea acabou de ver como criar um aplicativo da Web simples que sincroniza dados usando o PouchDB e o <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/\">Couchbase<\/a>. Este \u00e9 um aplicativo Angular 2 que \u00e9 um passo \u00e0 frente do aplicativo <a href=\"https:\/\/www.couchbase.com\/blog\/pt\/sync-with-couchbase-using-only-angularjs-and-pouchdb\/\">guia que escrevi no ano passado<\/a> que usava o 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\/pt\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\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\/pt\/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\":\"pt-BR\",\"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\":\"pt-BR\",\"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\":\"pt-BR\",\"@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\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@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\":\"pt-BR\",\"@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\/pt\/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\/pt\/using-couchbase-mobile-in-a-web-application-with-only-angular-2-and-pouchdb\/","og_locale":"pt_BR","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\/pt\/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":"pt-BR","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":"pt-BR","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":"pt-BR","@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":"Blog do Couchbase","description":"Couchbase, o banco de dados 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":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@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 dos desenvolvedores, Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@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 \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender.","sameAs":["https:\/\/www.thepolyglotdeveloper.com","https:\/\/www.facebook.com\/thepolyglotdeveloper","https:\/\/x.com\/nraboy"],"url":"https:\/\/www.couchbase.com\/blog\/pt\/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 \u00e9 um defensor das modernas tecnologias de desenvolvimento m\u00f3vel e da Web. Ele tem experi\u00eancia em Java, JavaScript, Golang e uma variedade de estruturas, como Angular, NativeScript e Apache Cordova. Nic escreve sobre suas experi\u00eancias de desenvolvimento relacionadas a tornar o desenvolvimento m\u00f3vel e da Web mais f\u00e1cil de entender."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2477","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/63"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=2477"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/2477\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=2477"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=2477"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=2477"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=2477"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}