Skip to content

Instantly share code, notes, and snippets.

@jbsulli
Last active April 3, 2018 18:17
Show Gist options
  • Save jbsulli/48359efd749947e4074387537ac5275f to your computer and use it in GitHub Desktop.
Save jbsulli/48359efd749947e4074387537ac5275f to your computer and use it in GitHub Desktop.
MobX 4 extendObservable issue

The Problem:

Given the folloowing code:

class Jedi {
  @observable firstName = "";
  @observable lastName = "";

  constructor(options) {
    extendObservable(this, options);
  }
}

If options has firstName and lastName, the result will be that firstName and lastName will be "" (the default defined above) not the values found in options.

What I THINK is Happening:

I know that the following code was working before the update (it was in our codebase):

class Silly {
  @observable thing = observable(true);
}

That code no longer works in MobX 4.0.0. It's a little silly but easy to fix. However, I believe this is what is happening under the hood when you use extendObservable() to set fields that are already defined as observable.

Solutions:

A:

class Jedi {
  // don't define firstName/lastName here
  
  constructor(options) {
    extendObservable(this, options);
  }
}

B:

class Jedi {
  @observable firstName = "";
  @observable lastName = "";
  
  constructor({ firstName, lastName }) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

C:

class Jedi {

  @observable firstName = "";
  @observable lastName = "";
  
  constructor(options) {
    // write/find a util function that sets all observable properties on the class
    // ignoring options that are not defined on the class or are computeds/actions/functions
    initializeObservable(this, options);
  }
}

How extendObservable() is (Probably) Meant to be Used:

class DimensionsById {
  constructor(dimensions) {
    const idMap = {};
    dimensions.forEach(dim => idMap[dim.id] = dim);

    // we don't know what the fields are going to be until runtime
    // so lets use extendObservable!
    extendObservable(idMap);
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment