Cómo hacer un CRUD en Angular sin base de datos

Carlos Galeano ⚡
5 min readAug 9, 2020

--

El CRUD (Create, Read, Update and Delete) forma una parte importante en el desarrollo de muchas aplicaciones webs, las cuales necesitan realizar operaciones fundamentales de crear, leer, actualizar y eliminar datos, es decir, un CRUD manipulando los datos de acuerdo a ciertas necesidades. En esta guía tocaremos cómo realizar simples operaciones de gestión de datos en una aplicación de Angular, sin la necesidad de realizar peticiones a un servidor, todo sucederá desde el lado del cliente.

Para dar inicio, he preparado un template para poder trabajar el uso del CRUD en Angular,

lo puedes clonar si así lo deseas de este repositorio en GitHub.

Manos a la obra

Bueno, entrando en materia, el primer paso sería instalar la librería angular-in-memory-web-api en nuestro proyecto vía npm, la cual nos ofrece un demo y tests que emulan las operaciones CRUD sobre una REST API.

Una vez instalado es importante realizar la importación en el módulo que se desea trabajar, en el caso del templete usare el módulo principal para configurar este proyecto. Me dirigo al app.module.ts y escribo lo siguiente:

import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';imports: [.
.
.
HttpClientInMemoryWebApiModule.forRoot()],export class AppModule { }

Ya estando importado en el módulo principal y declarado en el array de imports, en el método forRoot() debemos pasarle como parámetro la data, o mejor dicho, una base de datos interna creada en el proyecto. Nos vamos a la carpeta app del proyecto y allÍ podemos crear un archivo .ts, lo pueden nombrar como quieran, en mi caso será api.data.ts. Ahí alojaremos la información que será consultada más adelante.

Ahora, ¿cómo configurar esa base de datos?, sencillo, debemos realizar lo siguiente:

import { InMemoryDbService } from 'angular-in-memory-web-api';export class DataExample implements InMemoryDbService {createDb() {const users = [ { id: 1, name: 'Carlos', lastName: 'Galeano', email:   'galeanocarlos@gmail.com', GitHub: 'Mister CG' }];   return {users};}}

Se crea un clase, el nombre es opcional respetando el UpperCamelCase, seguido de la importación del

InMemoryDbService que debe ser implementado en la clase como se ve en el ejemplo.

Se procede a crear la “base de datos” por medio del método createDb(), en este método podremos alojar distintas colecciones con la información que queramos, para este ejemplo he creado la colección de users y dentro de ella la información que corresponde a un usuario.

Con esta parte lista, volvemos al app.module e importamos la clase DataExample y se la pasamos como parámetro al forRoot(), quedando así el módulo:

import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';import { DataExample } from './api.data';imports: [.HttpClientInMemoryWebApiModule.forRoot(DataExample)],

Claro, estamos trabajando con una api interna, pero aún así cumple ciertas funciones como si fuera una externa al proyecto, por eso tenemos que importar de angular el HttpClientModule en nuestro módulo para trabajarla por medio de peticiones http en un servicio que ya crearemos:

import { HttpClientInMemoryWebApiModule } from 'angular-in-memory-web-api';import { HttpClientModule } from '@angular/common/http';import { DataExample } from './api.data';imports: [
.
.HttpClientModule,HttpClientInMemoryWebApiModule.forRoot(DataExample)],

Para crear el servicio dentro de nuestro proyecto, se escribiría la siguiente línea de comandos en la terminal ng generate service service/apidata --skipTests=true, esta nos generara un servicio llamado ApidataService dentro de una carpeta service, y saltándose la creación del archivo de prueba *.spec.ts.

import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';import { Observable } from 'rxjs';import { Users } from '../interface/user.data';@Injectable({provided In: 'root'})export class ApidataService {urlApi = 'api/users';constructor(private http: HttpClient) { }getUsers(): Observable<Users[]> {return this.http.get<Users[]>(this.urlApi);}updateUser(user: Users) {return this.http.put(this.urlApi, user);}deleteUser(id: number) {return this.http.delete(this.urlApi+'/'+id);}addUser(user: Users){return this.http.post(this.urlApi, user);}}

Así queda el código del servicio que realiza las peticiones HTTP, en otros términos, el GET, POST, PUT, DELETE realizan el CRUD completo, puedo leer la información a través de GET, puedo crear nuevos usuarios por medio de POST, actualizar sus datos con PUT y eliminarlo con DELETE. Para poder trabajar con dichas peticiones solo debo importar HttpClient como se muestra allí, y el Observable sirve como una representación de valores durante cualquier cantidad tiempo, y por supuesto, la url a la que le haremos las peticiones se la pasamos como parámetro a cada petición.

Con esto podemos trabajarlo en algún componente de nuestro proyecto, extrayendo la datos y pasándole información que nosotros deseamos. Este ejemplo lo podrás ver por medio de formularios si clonaste el template que te mencione arriba podrás elegir entre reactive o template — tomando la información existente, creando nuevos usuarios, modificandolos o eliminandolos.

Como va quedando el componente:

import { ApidataService } from '../../service/apidata.service';@Component({selector: 'app-reactive',templateUrl: './reactive.component.html',styleUrls: ['./reactive.component.css']})export class ReactiveComponent implements OnInit {constructor(private api: ApidataService){}ngOnInit() {this.getUsers();}getUsers() {return this.api.getUsers().subscribe(res => this.users = res);}addUser(){this.api.addUser(this.form.value => 'Así va el resultado de form').subscribe(res =>   this.getUsers());}deleteUser(id: number){this.api.deleteUser(id => 'El id de usuario').subscribe(res => this.getUsers());}updateUser(user: Users){return this.api.updateUser(user =>'El usuario completo').subscribe(res => this.getUsers());}}

Así se ve el template:

Los campos llenado correctamente te permitirán crear un nuevo usuario que corresponde a una petición POST, y abajo podrás modificarlo/eliminarlo siendo peticiones PUT o DELETE respectivamente. La información la podemos pasar atreves de eventos que se comuniquen con los métodos mostrados arriba, un pequeño ejemplo de cómo podría ser por medio del html

<button class="btn btn-success right" [disabled]="formUser.invalid" (click)="addUser()">Mostrar en tabla</button>.
<!--Eliminar el usuario-->
<span class="material-icons" id="icon-right" (click)="deleteUser(user.id)"></span><!--Se capturan los datos de la modificacion del usuario--><button type="button" class="btn btn-success" [disabled]="formUserUpdate.invalid" (click)="modalRef.hide()" (click)="updateUser(formUserUpdate.value)">Actualizar datos</button>

Conclusión

Ya con esto puedes usar la librería como un pequeño demo para realizar CRUD sin backend y base de datos, todo se realiza dentro del mismo proyecto.

Si deseas ver el código completo del template con la implementación del angular-in-memory-web-api puedes darle click aquí. También puedes ver un demo de todo el proyecto completo en esta página.

--

--