{"id":3673,"date":"2017-06-05T02:03:15","date_gmt":"2017-06-05T09:03:15","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=3673"},"modified":"2023-06-19T02:15:21","modified_gmt":"2023-06-19T09:15:21","slug":"persist-abstract-data-nativescript-typescript-application","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/es\/persist-abstract-data-nativescript-typescript-application\/","title":{"rendered":"Persistir y abstraer datos en una aplicaci\u00f3n Typescript de Nativescript"},"content":{"rendered":"<p><a href=\"https:\/\/www.linkedin.com\/in\/aaron-ullal\/\">Aaron Ullal<\/a> es un\u00a0<em>Desarrollador freelance en FactoryMind, amante de la gente y de la vida, vive en beta permanente.  \u00c9l<\/em><em>\u00a0<\/em><em>es un desarrollador full stack con sede en la hermosa ciudad de Trento, Italia.<\/em><\/p>\n<p><em>IT apasionada por m\u00e1s <\/em><em>que <\/em><em>7 a\u00f1os, es <\/em><em>actualmente<\/em><em>\u00a0centrado en el desarrollo m\u00f3vil con Native<\/em><em>S<\/em><em>cript y el dise\u00f1o de soluciones arquitect\u00f3nicas para plataformas complejas.<\/em><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-medium wp-image-3682\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/06\/AaronUllal-300x200.png\" alt=\"Aaron Ullal \" width=\"300\" height=\"200\" srcset=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/06\/AaronUllal-300x200.png 300w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/06\/AaronUllal-400x267.png 400w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/06\/AaronUllal-450x300.png 450w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/06\/AaronUllal-20x13.png 20w, https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/06\/AaronUllal.png 600w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<p>Couchbase es una gran herramienta para persistir datos dentro de nuestra app. Si no has o\u00eddo hablar de \u00e9l, es un almacenamiento de objetos de documentos que te permite guardar tus datos.<\/p>\n<p>Si est\u00e1s usando NativeScript-Angular, ya hay algunos tutoriales geniales sobre c\u00f3mo empezar y algunas caracter\u00edsticas m\u00e1s avanzadas. En este art\u00edculo nos centraremos en NativeScript con TypeScript.<\/p>\n<p><strong>Qu\u00e9 trataremos<\/strong><\/p>\n<p>En este sencillo art\u00edculo vamos a ver c\u00f3mo guardar y recuperar alguna informaci\u00f3n del usuario por:<\/p>\n<ol>\n<li>Instalaci\u00f3n de Couchbase<\/li>\n<li>Creaci\u00f3n de una clase TypeScript que proporciona una capa de abstracci\u00f3n sobre Couchbase, haci\u00e9ndolo mucho m\u00e1s f\u00e1cil de usar (sin instrucciones complejas para la inserci\u00f3n y recuperaci\u00f3n de datos).<\/li>\n<li>Implementaci\u00f3n del patr\u00f3n singleton en la clase<\/li>\n<\/ol>\n<p>Al final del tutorial seremos capaces de utilizar instrucciones como<\/p>\n<pre class=\"lang:default decode:true\">userSettings.name =\u00a0\"Frank\"\u00a0\/\/boom! written in our db\r\n\r\ntext=\u201d{{\u00a0userSettings.name }}\u201d\u00a0\/\/boom! read from our db<\/pre>\n<p>\u00a1sin tener que escribir extensas consultas para leer y escribir!<\/p>\n<p>Adem\u00e1s, todo el c\u00f3digo de este art\u00edculo est\u00e1 disponible en <u><a href=\"https:\/\/github.com\/ullalaaron\/nativescript-couchbase-demo\" target=\"_blank\" rel=\"noopener noreferrer\">este<\/a><\/u>\u00a0repositorio de GitHub. Si\u00e9ntete libre de clonarlo y probarlo.<\/p>\n<p>Sin m\u00e1s dilaci\u00f3n, \u00a1empecemos!<\/p>\n<p><strong>Instalar el plugin Couchbase<\/strong><\/p>\n<p>Vamos a crear una nueva aplicaci\u00f3n NativeScript utilizando la plantilla TypeScript.<\/p>\n<pre class=\"lang:default decode:true\">tns create ns-couchbase-demo --tsc<\/pre>\n<p>En la carpeta ra\u00edz de nuestro reci\u00e9n creado proyecto NativeScript, vamos a dar el siguiente comando para a\u00f1adir el plugin y guardarlo en nuestra lista de dependencias:<\/p>\n<pre class=\"lang:default decode:true\">tns plugin add nativescript-couchbase\r\n\r\n<\/pre>\n<p>Una vez que el plugin se ha instalado correctamente, vamos a crear una clase que vamos a utilizar para almacenar y recuperar la informaci\u00f3n de usuario que necesitamos.<\/p>\n<p><strong>Clase de capa de abstracci\u00f3n<\/strong><\/p>\n<p><strong>OPCIONAL: <\/strong>Suele ser una buena idea crear una interfaz para definir las propiedades que necesitamos incluir.<\/p>\n<p>Navega a la carpeta app de nuestro proyecto y crea una carpeta models. Aqu\u00ed definiremos nuestro archivo Models.ts (app\/models\/Models.ts):<\/p>\n<pre class=\"lang:default decode:true\">export\u00a0module\u00a0Models{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0export\u00a0interface\u00a0IUserSettings\u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0username :string;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0fullname :string;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0email :string;\r\n\r\n}\r\n\r\n}\r\n\r\n<\/pre>\n<p>Una vez definida nuestra interfaz, vamos a crear la clase que la implementa. Llamaremos a la clase UserSettings.<\/p>\n<p>Dentro de esta clase tambi\u00e9n necesitamos almacenar la informaci\u00f3n relacionada con nuestra base de datos Couchbase.<\/p>\n<pre class=\"lang:default decode:true\">let CouchBaseModule\u00a0=\u00a0require(\"nativescript-couchbase\");\r\n\r\nimport\u00a0{\u00a0Models\u00a0}\u00a0from\u00a0'..\/models\/Models';\r\n\r\nexport\u00a0class\u00a0UserSettings implements Models.IUserSettings{\r\n\r\n\u00a0 \u00a0private\u00a0DATABASE_NAME =\u00a0'appname-db';\r\n\r\n\u00a0 \u00a0private\u00a0USER_SETTINGS_DOC_ID\u00a0=\u00a0'usersettings';\r\n\r\n\u00a0 \u00a0private\u00a0_database;\r\n\r\n\u00a0 \u00a0private\u00a0_userSettingsDocument:\u00a0Models.IUserSettings;\r\n\r\n\u00a0 \u00a0private\u00a0_userSettingsObj:\u00a0Models.IUserSettings;\r\n\r\n\u00a0 \u00a0private _instance :UserSettings;\r\n\r\n}\r\n\r\n<\/pre>\n<p>Vamos a desglosarlo:<\/p>\n<p>En las dos primeras l\u00edneas requerimos el plugin de Couchbase que instalamos previamente junto con el m\u00f3dulo Models que utilizaremos para aprovechar el tipado fuerte de TypeScript.<\/p>\n<p>A continuaci\u00f3n, definimos algunas otras propiedades privadas que utilizaremos m\u00e1s adelante:<\/p>\n<p>NOMBRE_BASE_DE_DATOS: Es el nombre de la base de datos. Aseg\u00farate de que no contenga may\u00fasculas (y que tenga menos de 240 caracteres).<\/p>\n<p>USER_SETTINGS_DOC_ID: Nombre del documento Couchbase.<\/p>\n<p>base de datos: Es la instancia del conector de base de datos.<\/p>\n<p>_userSettingsDocument: Couchbase es una base de datos No orientada a documentos. No tiene tablas, en su lugar utiliza una entidad de almacenamiento primaria conocida como Documento. B\u00e1sicamente un documento es una colecci\u00f3n de pares clave-valor, donde el valor puede ser pr\u00e1cticamente cualquier cosa (cadena, n\u00fameros, matrices, etc.). Esto es lo que hace de Couchbase la soluci\u00f3n n\u00famero uno si necesitas almacenar una variedad de datos no relacionales: simplicidad y flexibilidad.<\/p>\n<p>_userSettingsObj: Es el objeto JavaScript que utilizaremos para sincronizar la informaci\u00f3n con el documento de Couchbase.<\/p>\n<p>Veremos por qu\u00e9 declaramos la variable _instance m\u00e1s adelante, cuando implementemos el patr\u00f3n singleton.<\/p>\n<p>Ahora que tenemos esto cubierto, veamos c\u00f3mo funciona el constructor de nuestra clase:<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\">constructor()\u00a0{\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0this._database =\u00a0new\u00a0CouchBaseModule.Couchbase(this.DATABASE_NAME);\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0this._userSettingsDocument =\u00a0this._database.getDocument(this.USER_SETTINGS_DOC_ID);\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0if\u00a0(!this._userSettingsDocument)\u00a0{\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0console.log(\"Document does not exist yet :)\");\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0this._userSettingsObj =\u00a0{\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0username:\u00a0\"\",\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0email:\u00a0\"\",\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0fullname:\u00a0\"\",\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0}\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0this._database.createDocument(this._userSettingsObj,\u00a0this.USER_SETTINGS_DOC_ID);\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0this._userSettingsDocument =\u00a0this._database.getDocument(this.USER_SETTINGS_DOC_ID);\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0}\r\n\r\n\u00a0 \u00a0}\r\n\r\n<\/pre>\n<p>Una vez m\u00e1s, vamos a ver en detalle lo que est\u00e1 pasando en nuestro constructor:.<\/p>\n<p>this._database = new CouchBaseModule.Couchbase(this.DATABASE_NAME);<\/p>\n<p>Aqu\u00ed estamos instanciando Couchbase y diciendo a qu\u00e9 base de datos queremos conectarnos.<\/p>\n<p>this._userSettingsDocument = this._database.getDocument(this.USER_SETTINGS_DOC_ID);<\/p>\n<p>Esta l\u00ednea le dice a Couchbase que nos consiga nuestro documento (la colecci\u00f3n que usamos para almacenar nuestra informaci\u00f3n).<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\">\u00a0if\u00a0(!this._userSettingsDocument)\u00a0{\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0console.log(\"Document does not exist yet :)\");\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0this._userSettingsObj =\u00a0{\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0username:\u00a0\"\",\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0email:\u00a0\"\",\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0fullname:\u00a0\"\",\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0}\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0this._database.createDocument(this._userSettingsObj,\u00a0this.USER_SETTINGS_DOC_ID);\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0this._userSettingsDocument =\u00a0this._database.getDocument(this.USER_SETTINGS_DOC_ID);\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0}<\/pre>\n<p>&nbsp;<\/p>\n<p>Si nuestro documento a\u00fan no existe (por ejemplo, la primera vez), creamos un objeto vac\u00edo de tipo UserSettings y tambi\u00e9n creamos un nuevo documento. El segundo par\u00e1metro que asignamos a la funci\u00f3n createDocument es el id del documento. Si no proporcionamos este par\u00e1metro Couchbase asignar\u00e1 al documento un UUID autom\u00e1ticamente.<\/p>\n<p>\u00a1Fant\u00e1stico! Ahora que nuestro constructor est\u00e1 hecho, veamos c\u00f3mo podemos establecer y recuperar informaci\u00f3n sobre nuestro usuario.<\/p>\n<p>Vamos a configurar algunos getters y setters para lograr precisamente eso.<\/p>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\">\/*====== USERNAME GETTER AND SETTER ======*\/\r\n\r\n\u00a0 \u00a0get\u00a0username():\u00a0string\u00a0{\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0this._userSettingsObj =\u00a0this._database.getDocument(this.USER_SETTINGS_DOC_ID\r\n\r\n);\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0let username =\u00a0this._userSettingsObj.username;\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0return\u00a0username;\r\n\r\n\u00a0 \u00a0}\r\n\r\n\u00a0 \u00a0set\u00a0username(value:\u00a0string)\u00a0{\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0this._userSettingsObj =\u00a0this._database.getDocument(this.USER_SETTINGS_DOC_ID\r\n\r\n);\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0this._userSettingsObj.username =\u00a0value;\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0this._database.updateDocument(this.USER_SETTINGS_DOC_ID\r\n\r\n,\u00a0this._userSettingsObj);\r\n\r\n\u00a0 \u00a0}<\/pre>\n<p>Como de costumbre, desglosemos el c\u00f3digo.<\/p>\n<p>En el getter hacemos tres cosas:<\/p>\n<p>1) Leemos los datos de nuestro documento en nuestro objeto<\/p>\n<p>2) Obtener el valor deseado (en este caso el nombre de usuario)<\/p>\n<p>3) Devu\u00e9lvalo<\/p>\n<p>Muy f\u00e1cil :)<\/p>\n<p>En el setter hacemos lo siguiente:<\/p>\n<p>1) Obtenemos la \u00faltima versi\u00f3n de nuestro userSettingsObject ley\u00e9ndolo de la db<\/p>\n<p>2) Establecemos la propiedad username al valor pasado a la funci\u00f3n<\/p>\n<p>3) Actualizamos nuestro documento en la base de datos. A diferencia de la funci\u00f3n createDocument, el primer par\u00e1metro es el ID del documento y el segundo es el propio objeto.<\/p>\n<p>Pero ... \u00bfpor qu\u00e9 necesitamos primero getDocument? \u00bfPor qu\u00e9 no podemos simplemente actualizar el documento con el objeto?<\/p>\n<p>Me alegro de que preguntes.<\/p>\n<p>B\u00e1sicamente, cada vez que actualizamos un documento, Couchbase hace un seguimiento del cambio. Cada documento tiene una propiedad _rev; este valor es actualizado por Couchbase cada vez que se realiza una operaci\u00f3n de escritura sobre el documento. Si intentamos actualizar un documento con un _rev m\u00e1s antiguo, Couchbase lo rechazar\u00e1.<\/p>\n<p><strong>Patr\u00f3n Singleton<\/strong><\/p>\n<p>\u00bfA qui\u00e9n no le gustan los patrones de dise\u00f1o? Hoy vamos a implementar uno muy simple, pero efectivo: el singleton. El patr\u00f3n singleton, cuando se implementa correctamente, \"restringe la <a href=\"https:\/\/en.wikipedia.org\/wiki\/Instantiation_(computer_science)\" target=\"_blank\" rel=\"noopener noreferrer\">instanciaci\u00f3n<\/a>\u00a0de un <a href=\"https:\/\/en.wikipedia.org\/wiki\/Class_(computer_programming)\" target=\"_blank\" rel=\"noopener noreferrer\">clase<\/a>\u00a0a uno <a href=\"https:\/\/en.wikipedia.org\/wiki\/Object_(computer_science)\" target=\"_blank\" rel=\"noopener noreferrer\">objeto<\/a>. Esto es \u00fatil cuando se necesita exactamente un objeto para coordinar las acciones en todo el sistema\", que es exactamente nuestro caso.<\/p>\n<p>B\u00e1sicamente nos aseguramos de que s\u00f3lo tenemos una instancia de nuestra clase leyendo y escribiendo en nuestra base de datos.<\/p>\n<p>\u00bfC\u00f3mo lo hacemos? Una forma sencilla de conseguirlo es con los dos pasos siguientes:<\/p>\n<p>1) Hacer nuestro constructor privado (Introducido en ts 2.0)<\/p>\n<p>2) Implementar un m\u00e9todo getInstance que devuelva la instancia actual si existe, o una nueva si es la primera llamada.<\/p>\n<p>PASO 1:<\/p>\n<pre class=\"lang:default decode:true\">private\u00a0constructor()\u00a0{....}\r\n\r\n<\/pre>\n<p>PASO 2:<\/p>\n<p>Ahora podemos seguir adelante y crear nuestro m\u00e9todo getInstance() que se ver\u00e1 algo como esto:<\/p>\n<pre class=\"lang:default decode:true\">public\u00a0static\u00a0getInstance()\u00a0:UserSettings{\r\n\r\n\u00a0 \u00a0if(!this._instance){\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 this._instance =\u00a0new\u00a0UserSettings();\r\n\r\n\u00a0 \u00a0 }\r\n\r\nreturn\u00a0this._instance;\r\n\r\n}\r\n\r\n<\/pre>\n<p>Estupendo. Hemos abstra\u00eddo datos e implementado el patr\u00f3n singleton, sigamos adelante y veamos c\u00f3mo podemos utilizar nuestra nueva y brillante clase UserSettings.<\/p>\n<p>Vamos a editar los archivos existentes main-page.xml y main-page.ts.<\/p>\n<p>En primer lugar, definiremos el dise\u00f1o b\u00e1sico de la interfaz de usuario. Para esta demo usaremos un campo de texto para obtener la entrada del usuario, un bot\u00f3n para guardar el valor en la base de datos, y una etiqueta para mostrar el valor actual en la base de datos. Como puedes ver, si no hay datos almacenados en la base de datos la etiqueta simplemente mostrar\u00e1 \"No hay datos almacenados en la base de datos\".<\/p>\n<p>Este es el aspecto que deber\u00eda tener nuestro archivo main-page.xml:<\/p>\n<pre class=\"lang:default decode:true\">&lt;Page xmlns=\"https:\/\/schemas.nativescript.org\/tns.xsd\" navigatingTo=\"navigatingTo\"&gt;\r\n\r\n\u00a0 \u00a0 &lt;Page.actionBar&gt;\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;ActionBar title=\"My App\" icon=\"\" class=\"action-bar\"&gt;\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;\/ActionBar&gt;\r\n\r\n\u00a0 \u00a0 &lt;\/Page.actionBar&gt;\r\n\r\n\u00a0 \u00a0 &lt;StackLayout&gt;\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;TextField hint=\"username\" text=\"{{ username }}\" \/&gt;\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;Button text=\"SAVE MY USERNAME\" tap=\"onTap\" class=\"btn btn-primary btn-active\"\/&gt;\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 &lt;Label text=\"{{ dbusername || 'no data stored in the db' }}\" textWrap=\"true\"\/&gt;\r\n\r\n\u00a0 \u00a0 &lt;\/StackLayout&gt;\r\n\r\n&lt;\/Page&gt;\r\n\r\n<\/pre>\n<p>De acuerdo. Ahora que tenemos un dise\u00f1o b\u00e1sico podemos proceder a a\u00f1adir algo de l\u00f3gica a la interfaz de usuario.<\/p>\n<p>Este es el aspecto que deber\u00eda tener nuestro archivo main-page.ts:<\/p>\n<pre class=\"lang:default decode:true\">import\u00a0{\u00a0Observable\u00a0}\u00a0from\u00a0'data\/observable'; \/\/bind data to our view\r\n\r\nimport\u00a0{\u00a0UserSettings\u00a0}\u00a0from\u00a0'.\/UserSettings'; \/\/woohoo our amazing database interaction layer\r\n\r\nimport\u00a0{\u00a0EventData\u00a0}\u00a0from\u00a0'data\/observable'; \/\/use with typescript for intellisense\r\n\r\nimport\u00a0{\u00a0Page\u00a0}\u00a0from\u00a0'ui\/page'; \/\/use with typescript for intellisense\r\n\r\nlet userSettings =\u00a0UserSettings.getInstance();\r\n\r\nlet mainPageViewModel;\r\n\r\nclass\u00a0MainPageViewModel\u00a0extends\u00a0Observable{\r\n\r\n\u00a0 \u00a0 public\u00a0username;\r\n\r\n\u00a0 \u00a0 public\u00a0dbusername\r\n\r\n\u00a0 \u00a0 constructor(){\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 super();\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 this.dbusername =\u00a0userSettings.username;\r\n\r\n\u00a0 \u00a0 }\r\n\r\n}\r\n\r\nexport\u00a0function\u00a0navigatingTo(args:\u00a0EventData)\u00a0{\r\n\r\n\u00a0 \u00a0 let page =\u00a0&lt;Page&gt;args.object;\r\n\r\n\u00a0 \u00a0 mainPageViewModel =\u00a0new\u00a0MainPageViewModel();\r\n\r\n\u00a0 \u00a0 page.bindingContext =\u00a0mainPageViewModel;\r\n\r\n}\r\n\r\nexport\u00a0function\u00a0onTap(){\r\n\r\n\u00a0 \u00a0 userSettings.username =\u00a0mainPageViewModel.username;\r\n\r\n\u00a0 \u00a0 mainPageViewModel.set(\"dbusername\",userSettings.username);\r\n\r\n}\r\n\r\n<\/pre>\n<p>\u00bfQu\u00e9 hemos hecho? En las primeras l\u00edneas acabamos de importar un mont\u00f3n de cosas, comprobando los comentarios para ver lo que hacen los m\u00f3dulos. A continuaci\u00f3n tenemos:<\/p>\n<pre class=\"lang:default decode:true\">let userSettings =\u00a0UserSettings.getInstance();\r\n\r\n<\/pre>\n<p>As\u00ed es como obtenemos una instancia de nuestra clase UserSettings.<\/p>\n<p>Continuando, declaramos otra clase peque\u00f1a:<\/p>\n<pre class=\"lang:default decode:true\">class\u00a0MainPageViewModel\u00a0extends\u00a0Observable{\r\n\r\n\u00a0 \u00a0 public\u00a0username;\r\n\r\n\u00a0 \u00a0 public\u00a0dbusername\r\n\r\n\u00a0 \u00a0 constructor(){\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 super();\r\n\r\n\u00a0 \u00a0 \u00a0 \u00a0 this.dbusername =\u00a0userSettings.username;\r\n\r\n\u00a0 \u00a0 }\r\n\r\n}\r\n\r\n<\/pre>\n<p>Como puedes ver MainPageViewModel extiende la clase Observable. Si no est\u00e1s familiarizado con los Observables, debes saber que son b\u00e1sicamente objetos JavaScript que activan una notificaci\u00f3n si una de sus propiedades cambia. Puedes encontrar m\u00e1s informaci\u00f3n en <u><a href=\"https:\/\/docs.nativescript.org\/cookbook\/data\/observable\" target=\"_blank\" rel=\"noopener noreferrer\">aqu\u00ed<\/a><\/u>.<\/p>\n<p>Nuestro modelo de vista tiene dos propiedades: username (que vinculamos a nuestro campo de texto) y dbusername (que vinculamos a nuestra etiqueta). Cada vez que creamos una nueva instancia de nuestra clase asignamos a dbusername cualquier valor presente en nuestra instancia userSettings, que a su vez va y lee datos en nuestra base de datos (\u00bfrecuerdas nuestro m\u00e9todo get username() getter?).<\/p>\n<pre class=\"lang:default decode:true\">export\u00a0function\u00a0navigatingTo(args:\u00a0EventData)\u00a0{\r\n\r\n\u00a0 \u00a0 let page =\u00a0&lt;Page&gt;args.object;\r\n\r\n\u00a0 \u00a0 mainPageViewModel =\u00a0new\u00a0MainPageViewModel();\r\n\r\n\u00a0 \u00a0 page.bindingContext =\u00a0mainPageViewModel;\r\n\r\n}<\/pre>\n<p>Esta funci\u00f3n es llamada cada vez que navegamos a nuestra p\u00e1gina. Instanciamos nuestra clase MainPageViewModel y la asignamos a la variable mainPageViewModel y la enlazamos a nuestra p\u00e1gina. Simple y llanamente.<\/p>\n<p>Por \u00faltimo, pero no menos importante, definimos el comportamiento para el clic del bot\u00f3n:<\/p>\n<pre class=\"lang:default decode:true\">export\u00a0function\u00a0onTap(){\r\n\r\n\u00a0 \u00a0 userSettings.username =\u00a0mainPageViewModel.username;\r\n\r\n\u00a0 \u00a0 mainPageViewModel.set(\"dbusername\",userSettings.username);\r\n\r\n}<\/pre>\n<p>Una vez m\u00e1s, muy simple: Escribimos en la base de datos el valor de nuestro campo de texto (mainPageViewModel.username est\u00e1 vinculado al campo de texto) y luego actualizamos el valor de dbusername para actualizar la etiqueta. Una imagen vale m\u00e1s que mil palabras, \u00a1as\u00ed que aqu\u00ed va un GIF!<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-5669 size-full\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/06\/ezgif-2-b128d6c35c-compressor.gif\" alt=\"\" width=\"480\" height=\"768\" \/><\/p>\n<p><a href=\"https:\/\/www.couchbase.com\/blog\/es\/community\/community-writers-program\/\"><em>Este post forma parte del Programa de Escritura de la Comunidad Couchbase<\/em><\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Couchbase es una gran herramienta para persistir datos dentro de nuestra app. Si no has o\u00eddo hablar de \u00e9l, es un almacenamiento de objetos de documentos que te permite guardar tus datos.<\/p>\n<p>Si est\u00e1s usando NativeScript-Angular, ya hay algunos tutoriales geniales sobre c\u00f3mo empezar y algunas caracter\u00edsticas m\u00e1s avanzadas. En este art\u00edculo nos centraremos en NativeScript con TypeScript.<\/p>","protected":false},"author":53,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1814,1821,1816,1819],"tags":[1589],"ppma_author":[9026],"class_list":["post-3673","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-application-design","category-couchbase-architecture","category-couchbase-server","category-data-modeling","tag-nativescript"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.8 (Yoast SEO v25.8) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Persist and Abstract Data in a Nativescript Typescript Application - 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\/persist-abstract-data-nativescript-typescript-application\/\" \/>\n<meta property=\"og:locale\" content=\"es_MX\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Persist and Abstract Data in a Nativescript Typescript Application\" \/>\n<meta property=\"og:description\" content=\"Couchbase is a great tool to persist data inside our app. If you haven\u2019t heard of it, it\u2019s a document object storage that allows you to save your data.  If you are using NativeScript-Angular, there are already some great tutorials on how to get started and some more advanced features. In this article we\u2019ll focus on NativeScript with TypeScript.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/es\/persist-abstract-data-nativescript-typescript-application\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-06-05T09:03:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-06-19T09:15:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/06\/AaronUllal-300x200.png\" \/>\n<meta name=\"author\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Laura Czajkowski, Developer Community Manager, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/\"},\"author\":{\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220\"},\"headline\":\"Persist and Abstract Data in a Nativescript Typescript Application\",\"datePublished\":\"2017-06-05T09:03:15+00:00\",\"dateModified\":\"2023-06-19T09:15:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/\"},\"wordCount\":1443,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"keywords\":[\"nativescript\"],\"articleSection\":[\"Application Design\",\"Couchbase Architecture\",\"Couchbase Server\",\"Data Modeling\"],\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/\",\"name\":\"Persist and Abstract Data in a Nativescript Typescript Application - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2017-06-05T09:03:15+00:00\",\"dateModified\":\"2023-06-19T09:15:21+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#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\/persist-abstract-data-nativescript-typescript-application\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Persist and Abstract Data in a Nativescript Typescript Application\"}]},{\"@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\/5f1a0ece4e644bc8c037686fbc8f3220\",\"name\":\"Laura Czajkowski, Developer Community Manager, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g\",\"caption\":\"Laura Czajkowski, Developer Community Manager, Couchbase\"},\"description\":\"Laura Czajkowski is the Snr. Developer Community Manager at Couchbase overseeing the community. She\u2019s responsible for our monthly developer newsletter.\",\"url\":\"https:\/\/www.couchbase.com\/blog\/es\/author\/laura-czajkowski\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Persist and Abstract Data in a Nativescript Typescript Application - 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\/persist-abstract-data-nativescript-typescript-application\/","og_locale":"es_MX","og_type":"article","og_title":"Persist and Abstract Data in a Nativescript Typescript Application","og_description":"Couchbase is a great tool to persist data inside our app. If you haven\u2019t heard of it, it\u2019s a document object storage that allows you to save your data.  If you are using NativeScript-Angular, there are already some great tutorials on how to get started and some more advanced features. In this article we\u2019ll focus on NativeScript with TypeScript.","og_url":"https:\/\/www.couchbase.com\/blog\/es\/persist-abstract-data-nativescript-typescript-application\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-06-05T09:03:15+00:00","article_modified_time":"2023-06-19T09:15:21+00:00","og_image":[{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2017\/06\/AaronUllal-300x200.png","type":"","width":"","height":""}],"author":"Laura Czajkowski, Developer Community Manager, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Laura Czajkowski, Developer Community Manager, Couchbase","Est. reading time":"8 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/"},"author":{"name":"Laura Czajkowski, Developer Community Manager, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/5f1a0ece4e644bc8c037686fbc8f3220"},"headline":"Persist and Abstract Data in a Nativescript Typescript Application","datePublished":"2017-06-05T09:03:15+00:00","dateModified":"2023-06-19T09:15:21+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/"},"wordCount":1443,"commentCount":1,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","keywords":["nativescript"],"articleSection":["Application Design","Couchbase Architecture","Couchbase Server","Data Modeling"],"inLanguage":"es","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/","url":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/","name":"Persist and Abstract Data in a Nativescript Typescript Application - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2017-06-05T09:03:15+00:00","dateModified":"2023-06-19T09:15:21+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/persist-abstract-data-nativescript-typescript-application\/#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\/persist-abstract-data-nativescript-typescript-application\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Persist and Abstract Data in a Nativescript Typescript Application"}]},{"@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\/5f1a0ece4e644bc8c037686fbc8f3220","name":"Laura Czajkowski, Directora de la Comunidad de Desarrolladores, Couchbase","image":{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/9deb07d5daaa00220534c31768bc4409","url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","caption":"Laura Czajkowski, Developer Community Manager, Couchbase"},"description":"Laura Czajkowski es la Snr. Developer Community Manager en Couchbase supervisando la comunidad. Es responsable de nuestro bolet\u00edn mensual para desarrolladores.","url":"https:\/\/www.couchbase.com\/blog\/es\/author\/laura-czajkowski\/"}]}},"authors":[{"term_id":9026,"user_id":53,"is_guest":0,"slug":"laura-czajkowski","display_name":"Laura Czajkowski, Developer Community Manager, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/bc8eebaf25cbe39bc12fd7b1ef92550becc3953ab877a3f0285a59ec2d30b754?s=96&d=mm&r=g","author_category":"","last_name":"Czajkowski","first_name":"Laura","job_title":"","user_url":"","description":"Laura Czajkowski es la Snr. Developer Community Manager en Couchbase supervisando la comunidad. Es responsable de nuestro bolet\u00edn mensual para desarrolladores."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/3673","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\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/comments?post=3673"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/posts\/3673\/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=3673"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/categories?post=3673"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/tags?post=3673"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/es\/wp-json\/wp\/v2\/ppma_author?post=3673"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}