0

I have an overview of houses, each house has an image which is shown inside of a cart. Since the houses are async, I want to show empty cards as long as they are not fetched. To do so I added empty objects to the array to imply houses. This works fine as long as I don't add typing to houses. After adding Typescript hates me because the object obviously don't contain the correct properties.

I know removing typing would be a solution, but I guess not a good practice. Making all properties optional isn't a good practice either, I guess. Do I have to create mocks having these properties (which would be a lot) or is there a proper way to do that?

houses: House[] = [{}, {}, {}, {}, {}];

ngOnInit(): void {
  this.housesService.getGreatHouses().subscribe(houses => {
    if (houses && houses.length > 0) {
      this.houses = houses;
    }
  });
}
3
  • 1
    You can define your houses like this : houses: House[] = Array(5).fill(new House()) Commented Oct 9, 2020 at 20:37
  • Just to point out one thing in @Eldar's comment, all the elements of the created array will be the same references that is houses[0] === houses[1] will betrue. In .fill the expression is calculated first, and then the array is filled with returned value of the expression. Commented Oct 9, 2020 at 21:26
  • So if you update one card/element of the array, the result will be reflected in all cards/elemetns. Commented Oct 9, 2020 at 21:27

1 Answer 1

1

Option a:

// Partial<> makes all the properties of House optional:
houses: Partial<House>[] = [{}, {}, {}, {}, {}];

ngOnInit(): void {
  this.housesService.getGreatHouses().subscribe(houses => {
    // you need TypeScript >= 3.7 for the save navigation operator `?.`
    houses?.forEach((house, index) => {
       Object.assign(this.houses[index], house);
    });
  });
}

Option b:

// The House properties are all there filled with null. 
houses: House[] = [{ id: null, picture: null, ... }, { id: null, picture: null, ... },{ id: null, picture: null, ... }, ...];

// values assigned the same way as above

Probably that's where you'll want to make House a class (Model) and not an interface or type, so you don't have to do all that scaffold manually and anyhow get the features of instances and so forth.

Option B is pretty much that what @Eldar suggests in the comment. And It probably is the cleaner and in scale the more performant solution.

Why is it cleaner and at scale more performant?

Having an objects properties added or even worse removed (delete obj.property) prevents allot of the JavaScript interpreters ways to oprimize code at runtime. And besides that the structures are also more explicit and in the end the code will render much easyer to debug if the structures are predictable and not constantly transformed at runtime.

Sign up to request clarification or add additional context in comments.

Comments

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.