0

I am trying to create a decorator in Angular that allows me to mark certain properties of a component as "Options" with a specific type. The goal is to add these marked properties to a list that stores all the options. Later, I would like to call a function called getOptions(), which should return a Map containing the option names and their corresponding property keys.

I came across this Stack Overflow answer that seems similar to my goal. However, when I tried implementing it, I encountered an error stating "Uncaught TypeError: Cannot assign to read-only property 'Symbol(fields)' of object '[object Object]'".

I would greatly appreciate any help resolving this issue and suggestions or alternative approaches to achieve my desired functionality.

Ideally, I would like to achieve the following:

@Component({...})
export class DashboardComponent {
    @OptionType('ColorOption')
    color: string = "";
    ...

    ngOnInit(): void {
         console.log(getAllProperties()); // Should return <<color, ColorOption>>
    }
}

I've also created a Codesandbox, where you can find a working (but not correct) example and can try out your stuff! If you need any more information, feel free to ask!

Highnoon
  • 64
  • 5

1 Answers1

0

I've answered it myself. Basically, the decorator was a bit off. I created a fully working Codesandbox for everyone whos curious.

Additionally, in the following you can find the decorator as code:

/**
 * OptionType is a decorator function that can be used to annotate class properties with a specific options type.
 * @param optionsType - The options type for the annotated property.
 * @returns A decorator function that adds the options type to the target object.
 */
export function OptionType(optionsType: OptionsType) {
  return function (target: any, key: string) {
    // Check if the target object has a property called FIELDS
    if (!target[OPTIONS_FIELD_PROP_NAME]) {
      // If not, define the FIELDS property as a new Map
      Object.defineProperty(target, OPTIONS_FIELD_PROP_NAME, {
        value: new Map(),
        writable: false, // Prevent overwriting
        enumerable: false, // Enable enumeration
        configurable: false, // Prevent attribute changes, deletions, etc.
      });
    }

    // Set the optionsType value in the FIELDS map with the key as the property name
    target[OPTIONS_FIELD_PROP_NAME].set(key, optionsType);
  };
}
Highnoon
  • 64
  • 5