Home > Enterprise >  How to properly accept different object type in Component
How to properly accept different object type in Component

Time:03-17

Suppose I have an Angular component that can accept object of different type/interface. What is the correct way to handle it in the Component/Template (Or maybe it's a code smell to have this kind of requirement?)

For example, I have

@Component({
  selector: ''
})
export class ResultComponent {
  @Input() Item : GenericItem | AdvancedtItem; 
  //Item can be Generic or Advanced. I am not sure if using | is correct here
}

Should I try to type cast? If so, where should I do that so I can access the propeties in template?

Note: AdvancedItem may or may not extends GenericItem

If I do not use Typescript's typing, basically I can do this in the template

<div *ngIf="Item.SomeDiscriminatorProperty"> //do specific stuffs here </div>

Edit: I think without forcing type I would have some property check to display not display things and it is a quite normal thing to do in a template (Like above).

After I have given it some thought, Maybe it's best to create a new class DisplayableItem that have all the properties of AdvancedItem and GenericItem that I need to display and intentionally leave some fields as null

CodePudding user response:

It sounds like you haven't really thought your design through sufficiently.

If you really have two different types, perhaps you should have two different components?

Or maybe two different inputs?

In any case, I would keep the template a simple as possible. It is, after all, a "view" in MVC terms. Put as much of the logic (type wrangling, etc) in the component as possible, and keep it out of the template.

CodePudding user response:

I use multiple methods to solve this kind of problem:

  1. Three components, one for the GenericItem and one the AdvancedItem and both call a third component (or multiple sub components) that has a common interface that I can feed with data coming from both items. For example I have a Brand item with a name, abbreviation and logo, a Country component with a name, an isoCode2 and a flag. Both can use a third TagObjectComponent that use a common interface with a name and an image and display those as a tag with a flag/logo and the name.
  2. One component with two inputs, GenericItem and AdvancedItem, then, when needed I use ngIf in the html code. I use this method when the two objects are close enough that I'll have a lot of common code and only a few ngIf while not being able to create a simple abstraction like the one before.
  3. Two components from scratch. Sometimes none of the previous method produce simple/readable code and I took it as a clear sign that I need to rethink my design.

Inputs with multiple types are bad because, as you said, you'll need to safeguard at multiple levels to figure which type of object you have. You'll end up implementing OnChanges and using two different variables in your code. That's a lot of code for the exact same result than a double input.

  • Related