How do we create multiple collections using Angular-in-memory-web-api? Not an issue with single collection. But I\'m not able to implement it f
The approach described in the Paul's answer is correct, however there is one detail I missed which I like to add: How do you specify genId
correctly, so it works for both collections?
The answer is referring to the "Heroes" example written in TypeScript (a superset of JavaScript), specifically the HTTP chapter.
There, a table heroes
is simulated by implementing:
export class InMemoryDataService implements InMemoryDbService {
createDb() {
const heroes = [
{ id: 11, name: 'Mr. Nice' },
{ id: 12, name: 'Narco' },
// ...
{ id: 20, name: 'Tornado' }
];
return {heroes};
}
// Overrides the genId method to ensure that a hero always has an id.
// If the heroes array is empty,
// the method below returns the initial number (11).
// if the heroes array is not empty, the method below returns the highest
// hero id + 1.
genId(heroes: Hero[]): number {
return heroes.length > 0 ? Math.max(...heroes.map(hero => hero.id)) + 1 : 11;
}
}
Now, if you add a 2nd collection crises
as shown in his answer, i.e.:
createDb() {
let heroes = [ { ... }, ... ];
let crises = [ { ... }, ... ];
return { heroes, crises };
// or { heroes: heroes, crises: crises }
}
how do you provide genId
for both collections (provided they are of type Hero
and Crises
)? Overloading, as you would do it in C#
does not work in TypeScript, it would throw an error ("Duplicate function implementation").
Solution:
I found out, that you can solve this issue with TypeScript's Generics as follows. Replace the otiginal genId
function by the following generic version:
genId(myTable: T[]): number {
return myTable.length > 0 ? Math.max(...myTable.map(t => t.id)) + 1 : 11;
}
What's important here is the part
: It means that type T
can be either Hero
or Crises
: So it will be invoked if the parameter passed is either of type Hero[]
or Crises[]
.
With that knowledge, adding a 3rd, 4th, ... class is simple: Just append the class. Say we want to add the class SuperHero
, then you just append it via | SuperHero
, so it would look like:
genId(myTable: T[]): number {
return myTable.length > 0 ? Math.max(...myTable.map(t => t.id)) + 1 : 11;
}
Note: As a prerequisite, all classes (Hero
, Crises
and SuperHero
) need to have a numeric id
property declared.
Useful links:
HTTP chapter of Angular Tutorial
In-Memory-Web-API: Custom genId
Can You Specify Multiple Type Constraints For TypeScript Generics?