Hace poco escribí un tutorial titulado, Creación de un almacén de perfiles de usuario con Node.js y una base de datos NoSQLya que es un tema y un caso de uso muy popular cuando se trata de bases de datos NoSQL. En ese tutorial, creamos una API usando Node.js y Couchbase para almacenar usuarios, información asociada a usuarios concretos y sesiones que caducan. Sin embargo, estaba estrictamente relacionado con el backend, sin interfaz de usuario.
Queríamos utilizar la API de almacenamiento de perfiles de usuario y comprender cómo crear, utilizando TypeScript y Angular, una página de perfil que se comunica con cada uno de los puntos finales de la API.
Este tutorial ha sido actualizado el 7 de enero de 2021 por Eric Bishard ¡para trabajar con Angular 11!
Antes de continuar, suponemos que ha seguido el tutorial anterior. También vamos a suponer que usted tiene la Angular CLI instalado.
Crear un proyecto Angular con los componentes necesarios
El front-end del cliente será rudimentario, pero lo construiremos desde cero. Desde una perspectiva de diseño, no se va a ver muy bien porque este tutorial es todo acerca de la funcionalidad y el trabajo con nuestra API, depende de ti si quieres que se vea bien y proporcionar una mejor UX.
Desde la CLI de Angular, ejecute el siguiente comando:
1 |
ng nuevo couchbase-angular-blog-aplicación |
El comando anterior creará un nuevo proyecto en la ruta CLI. Con el proyecto creado, necesitaremos crear un componente para cada una de nuestras páginas de aplicación esperadas.
Ejecute lo siguiente con la CLI de Angular:
1 2 3 4 |
ng g componente inicio de sesión ng g componente regístrese en ng g componente blogs ng g componente blog |
Se crearán cuatro componentes de perfil de usuario Angular, cada uno con archivos TypeScript y HTML apropiados. Antes de empezar a añadir lógica a ellos, tenemos que unirlos para fines de navegación utilizando la plantilla de perfil de usuario angular a continuación.
Abra el archivo src/app/app.module.ts e incluya lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
importar { BrowserModule } de @angular/platform-browser; importar { NgModule } de @angular/core; importar { Módulo de formularios } de @angular/forms; importar { HttpClientModule } de @angular/common/http; importar { AppComponent } de './app.component'; importar { Componente de inicio de sesión } de './login/login.component'; importar { RegistrarComponente } de './register/register.component'; importar { BlogsComponente } de './blogs/blogs.component'; importar { BlogComponent } de './blog/blog.component'; importar { MóduloRouter } de @angular/router; deje rutas = [ { ruta: '', redirectTo: Inicio de sesión, pathMatch: completo }, { ruta: Inicio de sesión, componente: Componente de inicio de sesión }, { ruta: registro, componente: RegistrarComponente }, { ruta: blogs, componente: BlogsComponente }, { ruta: blog, componente: BlogComponent } ]; @NgModule({ declaraciones: [ AppComponent, Componente de inicio de sesión, RegistrarComponente, BlogsComponente, BlogComponent ], importaciones: [ BrowserModule, Módulo de formularios, HttpClientModule, MóduloRouter, MóduloRouter.forRoot(rutas) ], proveedores: [], arranque: [AppComponent] }) exportar clase AppModule { } |
El código anterior fue creado por la CLI de Angular, sin embargo, añadimos algunas importaciones de módulos core y personalizados y los importamos junto con el módulo rutas
en el @NgModule
bloque.
Para activar nuestra navegación, necesitaremos actualizar un archivo. Abra el archivo src/app/app.component.html y sustituya todo el contenido por lo siguiente:
1 |
<enrutador-salida></enrutador-salida> |
En este punto, el proyecto de perfil de usuario tiene una configuración básica con angular.
Echemos un vistazo al manejo de la creación de perfiles de usuario y el inicio de sesión con la información de la cuenta.
Inicio de sesión y registro
La primera pantalla que verá el usuario es la de inicio de sesión. El propósito aquí es recoger un nombre de usuario y contraseña, enviarlo a la API, obtener un identificador de sesión como respuesta, y utilizarlo en cada página futura de la aplicación.
Abra el archivo src/app/login/login.component.ts e incluya el siguiente código TypeScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
importar { Componente, OnInit } de @angular/core; importar { HttpClient, HttpHeaders } de @angular/common/http; importar { Router } de @angular/router; @Componente({ selector: app-login, templateUrl: './ingreso.component.html', styleUrls: ['./login.component.css'] }) exportar clase Componente de inicio de sesión implementa OnInit { público entrada: cualquier; constructor(privado http: HttpClient, privado enrutador: Router) { este.entrada = { correo electrónico: '', contraseña: '' }; } ngOnInit(): void { } público inicio de sesión() { si (este.entrada.correo electrónico && este.entrada.contraseña) { deje cabeceras = nuevo HttpHeaders({ tipo de contenido: aplicación/json }); este.http.Correo electrónico:(http://localhost:3000/login, JSON.stringify(este.entrada), { cabeceras: cabeceras }) .suscríbase a(resultado => este.enrutador.navegue por([/blogs], { queryParams: resultado }) ); } } } |
Hay algunas cosas importantes que suceden en el código anterior, así que vamos a desglosarlo.
Nuestra intención es vincular un objeto a un formulario en el marcado HTML. Este objeto será el entrada
variable. En la constructor
establecemos cada posible propiedad como un valor vacío que se reflejará en la interfaz de usuario.
Cuando el usuario decide iniciar sesión, se establece la información de cabecera adecuada para la solicitud y se envía el objeto al servidor. Si tiene éxito, la respuesta será un objeto con el id de sesión. Vamos a pasarlo a la siguiente página como un parámetro de consulta.
El código HTML que se empareja con este TypeScript se encuentra en el proyecto src/app/login/login.component.html y tiene el siguiente aspecto:
Iniciar sesión
1 |
Una nota que debo mencionar aquí es que si usted escribe la contraseña incorrecta no hemos creado ninguna manera de dejar que el usuario sepa que el nombre de usuario o la contraseña utilizada no era correcta, de nuevo, la funcionalidad sólo aquí y usted tendrá que crear esa funcionalidad, ya que es un poco más allá de nuestra demostración básica.
Lo importante aquí es el uso del [(ngModel)]
que se utilizan para la vinculación de datos. También ofrecemos navegación a la página de registro a través de la función [routerLink]
atributo.
¿Qué aspecto tiene el componente de registro?
Abra el archivo src/app/register/register.component.ts e incluya el siguiente código TypeScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
importar { Componente, OnInit } de @angular/core; importar { HttpClient, HttpHeaders } de @angular/common/http; importar { Router } de @angular/router; @Componente({ selector: app-register, templateUrl: './register.component.html', styleUrls: ['./register.component.css'] }) exportar clase RegistrarComponente implementa OnInit { público entrada: cualquier; público constructor(privado http: HttpClient, privado enrutador: Router) { este.entrada = { nombre: '', apellido: '', correo electrónico: '', contraseña: '' }; } ngOnInit(): void { } público regístrese en() { si (este.entrada.correo electrónico && este.entrada.contraseña) { deje cabeceras = nuevo HttpHeaders({ tipo de contenido: aplicación/json }); este.http.Correo electrónico:(http://localhost:3000/account, JSON.stringify(este.entrada), { cabeceras: cabeceras }) .suscríbase a(() => este.enrutador.navegue por([Inicio de sesión]) ); } } } |
Te darás cuenta de que el código de registro es muy similar al código de inicio de sesión. Solo estamos recolectando datos del formulario y enviándolos a un punto final de API diferente.
El HTML correspondiente se encuentra en el proyecto src/app/register/register.component.html tiene este aspecto:
Regístrese en
1 |
El HTML contiene elementos de formulario vinculados con el [(ngModel)]
así como un enlace a la página de inicio de sesión.
Recuerda, después de haber iniciado sesión estamos pasando la sesión a las páginas específicas del usuario. Esto nos permitirá obtener nuestra información de usuario de nuestro almacén de perfiles.
Creación y visualización de artículos de blog para un usuario concreto en el almacén de perfiles
Tras iniciar sesión, el usuario accede a una página en la que puede ver una lista de los artículos del blog que ha escrito. Recuerda, nuestro backend está conectando documentos NoSQL a través de un id de perfil que estamos definiendo.
Para ver los artículos del blog, el identificador de sesión pasado desde la página anterior debe establecerse como cabecera en una petición. El resultado de la solicitud puede mostrarse inmediatamente en la pantalla.
Abra el archivo src/app/blogs/blogs.component.ts e incluya el siguiente código TypeScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
importar { Componente, OnInit } de @angular/core; importar { HttpClient, HttpHeaders } de @angular/common/http; importar { Router, Ruta activada } de @angular/router; @Componente({ selector: app-blogs, templateUrl: './blogs.component.html', styleUrls: ['./blogs.component.css'] }) exportar clase BlogsComponente implementa OnInit { privado sid: cadena; público entradas: cualquier; público constructor( privado http: HttpClient, privado enrutador: Router, privado ruta: Ruta activada ) { este.entradas = []; } público ngOnInit() { este.ruta.queryParams.suscríbase a(parámetros => { este.sid = parámetros["sid]; deje cabeceras = nuevo HttpHeaders({ autorización: 'Portador' + parámetros["sid] }); este.http.consiga(http://localhost:3000/blogs, { cabeceras: cabeceras }) .suscríbase a(resultado => { este.entradas = resultado; consola.registro(resultado) }); }); } público crear() { este.enrutador.navegue por([/blog], { queryParams: { "sid: este.sid } }); } } |
Este archivo sigue una estrategia similar a la forma en que gestionamos el inicio de sesión y el registro.
En cuanto a las variables, creamos una variable privada llamada sid
que contendrá la sesión pasada de la página anterior. La dirección entradas
será una matriz de entradas de blog para un individuo devuelto desde el punto final de la API.
Al cargar la página deberíamos estar mostrando las entradas del blog. Nunca es una buena idea cargar o solicitar datos desde dentro del archivo constructor
por lo que en su lugar utilizaremos el método ngOnInit
método.
1 2 3 4 5 6 7 8 9 10 11 |
público ngOnInit() { este.ruta.queryParams.suscríbase a(parámetros => { este.sid = parámetros["sid]; deje cabeceras = nuevo HttpHeaders({ autorización: 'Portador' + parámetros["sid] }); este.http.consiga(http://localhost:3000/blogs, { cabeceras: cabeceras }) .suscríbase a(resultado => { este.entradas = resultado; consola.registro(resultado) }); }); } |
En el ngOnInit
podemos obtener los parámetros pasados y construir una cabecera de autorización. A continuación, hacemos una solicitud contra nuestro punto final que contiene el encabezado.
Para crear una nueva entrada en el blog, podemos pasar la variable sid
a la siguiente ruta:
1 2 3 |
público crear() { este.enrutador.navegue por([/blog], { queryParams: { "sid: este.sid } }); } |
Esto es como lo que vimos con la pantalla de inicio de sesión.
El marcado HTML que alimenta la interfaz de usuario no será más complejo que la lógica TypeScript que la alimenta. El HTML se puede ver en el src/app/blogs/blogs.component.html así:
Blogs que ha escrito
|
{{ entry.blog.title }}
{{ entry.blog.content }}
La creación de una entrada de blog tendrá una lógica similar a la que ya hemos visto. Abra el proyecto src/app/blog/blog.component.ts e incluya el siguiente código TypeScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
importar { Componente, OnInit } de @angular/core; importar { HttpClient, HttpHeaders } de @angular/common/http; importar { Ruta activada } de @angular/router; importar { Ubicación } de @angular/common; @Componente({ selector: app-blog, templateUrl: './blog.component.html', styleUrls: ['./blog.component.css'] }) exportar clase BlogComponent implementa OnInit { privado sid: cadena; público entrada: cualquier; público constructor(privado http: HttpClient, privado ruta: Ruta activada, privado ubicación: Ubicación) { este.entrada = { título: '', contenido: '' }; } público ngOnInit() { este.ruta.queryParams.suscríbase a(parámetros => { este.sid = parámetros["sid]; }); } público guardar() { si (este.entrada.título && este.entrada.contenido) { deje cabeceras = nuevo HttpHeaders({ tipo de contenido: aplicación/json, autorización: 'Portador' + este.sid }); este.http.Correo electrónico:(http://localhost:3000/blog, JSON.stringify(este.entrada), { cabeceras: cabeceras }) .suscríbase a(() => este.ubicación.volver() ); } } } |
En el código anterior estamos inicializando los datos de nuestro formulario y recuperando el archivo sid
que se pasó desde la página anterior.
Cuando intentamos guardar la entrada, construimos una cabecera apropiada que contiene el id de sesión y luego la enviamos a la API con los datos del formulario. Una vez completado, podemos navegar hacia atrás en la pila.
El HTML de la interfaz de usuario de esta página se encuentra en el archivo src/app/blog/blog.component.html así:
Nueva entrada en el blog
Mantener la coherencia
Por defecto, Couchbase intentará ser rápido, lo que significa que puede devolver datos más rápido de lo que se actualizan los índices. Cuando esto ocurre, es posible que falten datos recién creados en los resultados.
Expliqué cómo corregir esto en un tutorial anteriorpero a continuación encontrará un breve resumen.
1 2 3 4 5 6 7 8 9 10 11 |
const consulta = `SELECCIONAR * DESDE `blog` DONDE tipo = blog Y pid = $PID;` const opciones = { scanConsistency: couchbase.QueryScanConsistency.SolicitarPlus, parámetros: { PID: solicitar.pid } } await grupo.consulta(consulta, opciones) .entonces((resultado) => { consola.registro(resultado.filas) respuesta.enviar(resultado.filas) }) .captura((e) => respuesta.estado(500).enviar(e)) |
En nuestra blogs
podemos definir la consistencia del escaneo, y en este caso, le estamos diciendo que espere hasta que el índice se haya actualizado antes de devolver los datos. Esta es una operación rápida, así que no pienses que se arrastrará cuando hagas esto. Simplemente no será tan rápido como por defecto.
En este punto, el front-end debería funcionar perfectamente con el back-end.
Para ejecutar ambos proyectos a la vez.
En primer lugar, asegúrese de que tiene instalado Couchbase y de que dispone de un bucket denominado blog
creado y el índice que creamos en el tutorial de la API.
A continuación, ejecuta la API REST de Node:
1 |
nodo servidor |
A continuación, ejecute el proyecto Angular:
1 |
ng servir |
Regístrate, inicia sesión, crea una o dos entradas de blog y asegúrate de que la ruta de blogs muestra cada uno de los blogs que has creado.
Formas de mejorar este proyecto
Como hemos mencionado antes, el proyecto podría utilizar algo de CSS y diseño personalizados, así como validación de formularios y alertas o notificaciones dado que el usuario ha intentado utilizar una contraseña incorrecta o el título del blog supera un determinado número de caracteres o si se ha producido un error porque la API no funciona correctamente.
Crear un Editar blog página y ruta y un enlace desde el título de las entradas del blog en el Blogs Ruta/Página.
Cree una navegación y un marco sofisticados para la aplicación.
Reordenar la lista de blogs en Blogs Ruta/Página o configurar la posibilidad de ordenar los blogs por título en orden ascendente o descendente.
Permita que los usuarios inicien sesión con identificadores sociales o utilice este proyecto que hemos creado y añada una ruta de portafolio y otras páginas de apoyo como inicio para su propio portafolio de desarrollador.
Crear un servicio Angular para manejar el id de sesión, de manera que no sea necesario pasarlo con cada evento de navegación.
Conclusión
Acabas de ver cómo crear un sencillo front-end cliente utilizando Angular 11 y TypeScript para el almacén de perfiles de usuario que vimos en un ejemplo anterior. Cada plantilla de perfil de usuario Angular es diferente, por supuesto. Este front-end de cliente es uno de los muchos ejemplos posibles de página de perfil de usuario de Angular Material para un front-end porque se trata de una aplicación modular full-stack. Esto significa que el backend puede estar en cualquier idioma y el front-end en cualquier otro.
El código terminado está disponible en GitHub en couchbaselabs / couchbase-angular-blog-app en GitHub.
Para obtener más información sobre el uso de Couchbase con Node.js, consulte la página Portal para desarrolladores de Couchbase.