Observable makes my properties unserializable

Example:

export class MaybeValue<T> {
  @observable
  public value: T;

  public hasValue: boolean;
  constructor(value: T) {
    this.value = value;
    this.hasValue = this.value != null;
  }

  public valueChanged() {
    this.hasValue = this.value != null;
  }
}

const boo = new MaybeValue<string>("hello");
console.log(JSON.stringify(boo)); // {"hasValue":true}

Crappy, super annoying workaround:

export class MaybeValue<T> {

  public value: T;

  public hasValue: boolean;
  constructor(value: T) {
    this.value = value;
    this.hasValue = this.value != null;
  }
  public setValue(val: T){
    this.value = val;
    this.valueChanged();
  }

  public valueChanged() {
    this.hasValue = this.value != null;
  }
}

const boo = new MaybeValue<string>("hello");
console.log(JSON.stringify(boo)); // {"hasValue":true, "value": "hello"}

Any way to “just” make it work?

JSON.stringify respects toJSON method, which bypasses enumerable check on descriptors.

toJSON() {
  return {hasValue: this.hasValue, value: this.value};
}

Alternatively, you can copy and make your own version of observable, to use true on enumerable of the descriptor.

2 Likes

Oh wow, how the heck did I not learn of toJSON before. Thanks!