Multiple collections in Angular-in-memory-web-api

前端 未结 3 1484
攒了一身酷
攒了一身酷 2021-02-01 13:28

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

3条回答
  •  鱼传尺愫
    2021-02-01 14:19

    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?

提交回复
热议问题