1

Okay say I have a class like this in angular 6:

export class Game {
 private readonly iD: number;
 private readonly name: string;
 private readonly genre: string;

constructor (iD: number,
        name: string,
        genre: string) {
    this.iD = iD;
    this.name = name;
    this.genre = genre;
}

getName(): string { return this.name }

Then I make my api Call that returns an array of games. In a class that looks something like this.

interface ApiGames {
  games: Game[];
}

@Injectable({
 providedIn: 'root'
})
export class GameRepository {
  private game: Game;
  private games: Game[] = [];

constructor(private ApiService: ApiService) {
}

retrieveGames(): void {
this.ApiService.getGames()
  .subscribe(
    (response: ApiGames) => {
      this.games = response.games;
      }
 );
}

getGames(): Game[] { return this.games }

So this obviously works but it doesn't instantiate the objects. So if call the getter getName() in a situation like this (in another component).

<div *ngFor="let game of gameRepository.getGames()">
 {{ game.getName() }}
</div>

It throws an error like TypeError: _v.context.$implicit.getName() is not a function

but if I change the instance variable to public is works like this.

<div *ngFor="let game of gameRepository.getGames()">
 {{ game.name }}
</div>

But I'm pretty sure that only works because i'm just type checking and its not creating an instance of a game... Is what i'm doing even worth it? I'm trying to implement better practices and move away from procedural programming.

1 Answer 1

2

Use rxjs to pipe a map which will return directly the array of your instances.

So your code should look something like:

retrieveGames(): void {
  this.ApiService.getGames()
    .pipe(
      map((response: ApiGames) => response.games.map(g => 
        new Game(g.id, g.name, g.genre)
      ))
    )
    .subscribe((games: Game[]) => console.log('games:', games));
}

So:

  1. fetch the games
  2. pipe a map which will transform all your data returned by the api into an array of Game instances
  3. Now in your subscribe you have directly the array of games as Game instances
Sign up to request clarification or add additional context in comments.

3 Comments

Awesome thank you. It worked fine, looks like i'll have to pickup RXJS in Action or something a learn a bit more. Do you think this is a good strategy overall? Or is OOP overkill with js? Does it have limitations?
About rxjs, that's really powerful. Do not think to it as a way to manage only async code. You can even manage a more general concept: the one of streams. You can dispatch events and the subscribers will receive these events. Something close to generator functions, but a bit more powerful. About OOP, that's absolutely fine as far as you use that entity somehow. If you use that only as "type checker" for properties, use interfaces. If instead you use them as entities, so you have also utility methods on it, etc etc, that's absolutely a good practice! hope it makes sense :)
It makes sense! I've just been working through Java books and noticed that the term Interface is completely different in typescript. But it seems like abstract classes and the ability to extend them is there. Anyway, thanks again for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.