How should we define the StateModel of states that have sub states but no properties of their own?

Viewed 53

Let's say we have a state that looks something like the example below but with a lot more properties.

export interface SomeStateModel {
    ThingAProp01 : string;
    ThingAProp02 : string;
    ThingAProp03 : string;
    ThingBProp01 : string;
    ThingBProp02 : string;
    ThingBProp03 : string;
    ThingCProp01 : string;
    ThingCProp02 : string;
    ThingCProp03 : string;
}

@State<SomeStateModel>({

    name     : 'someState',
    defaults : {
        ThingAProp01 : 'some value',
        ThingAProp02 : 'some value',
        ThingAProp03 : 'some value',
        ThingBProp01 : 'some value',
        ThingBProp02 : 'some value',
        ThingBProp03 : 'some value',
        ThingCProp01 : 'some value',
        ThingCProp02 : 'some value',
        ThingCProp03 : 'some value'
    }

})
@Injectable()
export class SomeState{}

This can become quite daunting to maintain and scroll through which will make us want to create sub states that might look something like this.

@State<ThingAStateModel>({
    name     : 'thingA',
    defaults : {
        Prop01: 'some value',
        Prop02: 'some value',
        Prop03: 'some value'
    }
})
@Injectable()
export class ThingAState{}


@State<ThingBStateModel>({
    name     : 'thingB',
    defaults : {
        Prop01: 'some value',
        Prop02: 'some value',
        Prop03: 'some value'
    }
})
@Injectable()
export class ThingBState{}


@State<ThingCStateModel>({
    name     : 'thingC',
    defaults : {
        Prop01: 'some value',
        Prop02: 'some value',
        Prop03: 'some value'
    }
})
@Injectable()
export class ThingCState{}

Then use them in our state like this

@State<????????>({

    name     : 'someState',
    children : [
        ThingAState,
        ThingBState,
        ThingCState
    ]

})
@Injectable()
export class SomeState{}

In case you didn't notice I replaced <SomeStateModel> with <????????> because I don't know what the state model should look like for something like this going by the documentation for creating sub-states. From my understanding, NGXS will automatically handle the child states as properties without them needing to be defined in the defaults option of the parent state. In that example, they still have properties defined on the parent state which are defined in the state model, not including the model for the child states. What should we do in regards to the state model if the data we want to split apart leaves states with no properties of their own? What if I need to make SomeState a child state of another state which eliminates that state's properties and State Model? I'm sure I'm not the only user to walk into a situation like this however I can't seem to google the right thing to find the answer, can someone explain how this has to be done?

1 Answers

in this case, you can use extends

In TypeScript, we can use common object-oriented patterns. One of the most fundamental patterns in class-based programming is being able to extend existing classes to create new ones using inheritance.

example

export class SubStateModel {
  public items!: string[];
}

const defaults = {
  items: [],
};

@State<SubStateModel >({
  name: 'marketplace',
  defaults,
})
@Injectable()
export class SubState extends MainState { }

resources for extends

Related