In-Memory-Web-API in Angular Standalone
March 15, 2024
On this page we will learn to create our Angular application using in-memory-web-api. In development phase of application using HTTP operations, we developers need dummy REST API to test application. Angular provides in-memory-web-api that creates dummy DB with our seed data. When we insert and update data in this DB, the changes take place only in memory.
Here I will create a standalone application using in-memory-web-api step-by-step.
1. Install In Memory Web API
To work with in-memory-web-api, we need to install it if already not installed. Use the below command.npm i angular-in-memory-web-api
"dependencies": { ------ "angular-in-memory-web-api": "^0.17.0", }
2. Create Class with InMemoryDbService
Create a class in your application implementingInMemoryDbService
and define createDb()
method.
inmemory-test-data.ts
import { InMemoryDbService } from 'angular-in-memory-web-api'; export class InmemoryTestData implements InMemoryDbService { createDb() { let bookDetails = [ { id: 11, name: 'Spring Boot by Krishn', category: 'Spring' }, { id: 12, name: 'Java Expert by James', category: 'Java' } ]; let writerDetails = [ { id: '100', name: 'Krishn', city: 'Varanasi' }, { id: '101', name: 'James', city: 'Mumbai' } ]; return { books: bookDetails, writers: writerDetails }; } }
The DB given above, creates following paths.
/api/books /api/writers
3. importProvidersFrom()
importProvidersFrom()
collects providers from all specified NgModule
. The importProvidersFrom()
is used in application injector or another environment injector but not in component providers. We can use importProvidersFrom()
with bootstrapApplication
and with providers
field of Route
in route configuration.
To enable in-memory-web-api in standalone application, use
importProvidersFrom()
as below.
app.config.ts
import { ApplicationConfig, importProvidersFrom } from '@angular/core'; import { provideHttpClient } from '@angular/common/http'; import { InMemoryWebApiModule } from 'angular-in-memory-web-api'; import { InmemoryTestData } from './inmemory-test-data'; export const APP_CONFIG: ApplicationConfig = { providers: [ provideHttpClient(), importProvidersFrom(InMemoryWebApiModule.forRoot(InmemoryTestData)) ] };
provideHttpClient()
makes HttpClient
available for dependency injection.
4. Delaying Response
In some cases we may need to test application when REST API is returning response with some delay. To enable this delay in our dummy DB, configure delay in milliseconds as below.export const APP_CONFIG: ApplicationConfig = { providers: [ provideHttpClient(), importProvidersFrom(InMemoryWebApiModule.forRoot(InmemoryTestData, {delay: 2000})) ] };
5. HTTP Operations
In my demo application, I performing HTTP operations for POST and GET methods. To test application with dummy data, we just need to use our dummy REST API URLs.book.service.ts
import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Book } from '../book'; @Injectable({ providedIn: 'root' }) export class BookService { constructor(private http: HttpClient) { } saveBook(book: Book): Observable<Book[]> { console.log(book); return this.http.post<Book[]>("/api/books", book); } findBookByCategory(category: string): Observable<Book[]> { const httpParams = new HttpParams().set('category', category); return this.http.get<Book[]>("/api/books", { params: httpParams }); } findWriterByCity(city: string): Observable<Book[]> { const httpParams = new HttpParams().set('city', city); return this.http.get<any[]>("/api/writers", { params: httpParams }); } }
import { Component, OnInit } from '@angular/core'; import { Observable } from 'rxjs'; import { BookService } from './services/book.service'; import { Book } from './book'; import { CommonModule } from '@angular/common'; @Component({ selector: 'app-book', standalone: true, imports: [CommonModule], templateUrl: './book.component.html' }) export class BookComponent implements OnInit { booksById$!: Observable<Book[]>; booksByCategory$!: Observable<Book[]>; writersByCity$!: Observable<any[]>; constructor(private bookService: BookService) { } ngOnInit() { this.addBook(); this.searchBookByCategory('Spring'); this.searchWriterByCity("Mumbai"); } addBook() { const book: Book = { id: 13, name: 'Spring Data by Neeraj', category: 'Spring' }; const data = this.bookService.saveBook(book); console.log(data); } searchBookByCategory(category: string) { this.booksByCategory$ = this.bookService.findBookByCategory(category); } searchWriterByCity(city: string) { this.writersByCity$ = this.bookService.findWriterByCity(city); } }
<h3>Books By Category</h3> <div *ngFor="let book of booksByCategory$ | async" > Id: {{book.id}}, Name: {{book.name}}, Category: {{book.category}} </div> <h3>Writers By City</h3> <div *ngFor="let writer of writersByCity$ | async" > Id: {{writer.id}}, Name: {{writer.name}}, City: {{writer.city}} </div>