Abhishek Patil
Abhishek Patil

Reputation: 11

Using Rete Library typescript inheritance makes properties readonly

In angular I am using rete library while creating composer I can add the Node when I try to change the values inside it throws an error saying trying to set to readonly properties I have attached Error image here is the code link GitHub - jktjoy/composed.

Rete extended like this

import { ClassicPreset, ConnectionBase, NodeBase } from 'rete';

export class ComposerNode<
  CustomPayload extends { name: string; id: string; },
  Inputs extends {
    [key in string]?: ComposerSocket;
  } = {
    [key in string]?: ComposerSocket;
  },
  Outputs extends {
    [key in string]?: ComposerSocket;
  } = {
    [key in string]?: ComposerSocket;
  },
  Controls extends {
    [key in string]?: ComposerControl;
  } = {
    [key in string]?: ComposerControl;
  }> extends ClassicPreset.Node<Inputs, Outputs, Controls> implements NodeBase {
  nodePayload: CustomPayload;

  constructor(node: CustomPayload) {
    super(node.name);
    this.selected = false;
    this.nodePayload = node;
  }
}

export class ComposerConnection<
  Main extends { name: string; id: string; },
  Source extends ComposerNode<Main> = ComposerNode<Main>,
  Target extends ComposerNode<Main> = ComposerNode<Main>
> extends ClassicPreset.Connection<Source, Target> implements ConnectionBase {
  constructor(
    source: Source,
    sourceOutput: keyof Source['outputs'],
    target: Target,
    targetInput: keyof Target['inputs']
  ) {
    super(source, sourceOutput, target, targetInput);
  }
}

export class ComposerSocket extends ClassicPreset.Socket {
  constructor(name: string) {
    super(name);
  }
}

export type InputControlOptions<N> = {
  label?: string;
  description?: string;
  readonly?: boolean;
  initial?: N;
  change?: (value: N) => void;
};

export class ComposerControl extends ClassicPreset.Control { }

export class ComposerBaseControl<T> extends ComposerControl {
  pKey: string;
  label: string;
  description?: string;
  options?: InputControlOptions<T>;
  value?: T;
  readonly: boolean;

  constructor(pKey: string, options?: InputControlOptions<T>) {
    super();
    this.pKey = pKey;
    this.options = options;
    this.readonly = !!this.options?.readonly;
    if (this.options?.initial) {
      this.value = this.options.initial;
    }
    this.label = this.options?.label || 'Control';
    this.description = this.options?.description;
  }

  setValue(value?: T): void {
    this.value = value; // ***** Getting error here
  }
}

export class ComposerTextControl extends ComposerBaseControl<string> { }
export class ComposerNumberControl extends ComposerBaseControl<number> {
  override setValue(value?: number): void {
    this.value = !value ? 0 : +value;
  }
}
export class ComposerDropdownControl extends ComposerBaseControl<string> {
  // TODO dropdown options could be label display or complex object or primitive types
  dropdownOptions: string[];
  constructor(pKey: string, dropdownOptions: string[], options?: InputControlOptions<string>) {
    super(pKey, options);
    this.dropdownOptions = dropdownOptions;
  }

}
export class ComposerCheckboxControl extends ComposerBaseControl<boolean> {
  override setValue(value?: boolean): void {
    this.value = new Boolean(value).valueOf();
  }
}

error it is giving:----

core.mjs:10592 ERROR TypeError: Cannot assign to read only property 'value' of object '[object Object]'
    at ComposerDropdownControl.setValue (composer.framework.ts:87:15)
    at ComposerDropdownControlComponent.onChange (composer-dropdown-control.component.ts:21:15)
    at ComposerDropdownControlComponent_Template_select_change_3_listener (composer-dropdown-control.component.html:4:15)
    at executeListenerWithErrorHandling (core.mjs:16778:16)
    at wrapListenerIn_markDirtyAndPreventDefault (core.mjs:16811:22)
    at HTMLSelectElement.<anonymous> (platform-browser.mjs:665:17)
    at _ZoneDelegate.invokeTask (zone.js:402:31)
    at core.mjs:10735:55
    at AsyncStackTaggingZoneSpec.onInvokeTask (core.mjs:10735:36)
    at _ZoneDelegate.invokeTask (zone.js:401:60)

Is my inheritance implementation wrong? The prototype is showing Node but the constructor is showing ComposerNode. I also tried by adding

constructor(node: CustomPayload) {
  super(node.name);
  Object.setPrototypeOf(this, ComposerNode.prototype);
}

enter image description here

Can someone help-me with this.

Git: https://github.com/jktjoy/composed

Stackblitz: https://stackblitz.com/edit/stackblitz-starters-lre5gw

Upvotes: 1

Views: 176

Answers (0)

Related Questions