Mobx: Consider implementing Symbol.toPrimitive on boxed primitives.

Created on 18 Sep 2016  路  6Comments  路  Source: mobxjs/mobx

Most helpful comment

I would love to give this a shot. 馃憤

All 6 comments

Hi @urugator, want to understand the relevance of toPrimitive , so I wrote a small test

class AppState {
    @observable timer = 0;

    foo() {
        console.log("timer", this.timer)
        console.log("timerlogging", +this.timer)
        console.log(`timerlogging2  ${this.timer}`)
    }
}

Then modifying timer and logging the values similar to the example... and it seems like console.log works just fine with boxed observables. I was running this in node 6.5.0 without any extra flags. What am I missing? Can you maybe provide a snippet/file which does not work as expected for you and write down the expected result?

Regarding implementation of your proposal:

I added

public [Symbol.toPrimitive](hint): T {
    return this.get()
}

after get() in lib/types/observablevalue.ts which at least compiles (with a warning about Symbol not being known in es5 mode). But neither with this implementation nor with the return 10/"hello"/... from the MDN example, I was able to actually see the expected result in the console.

Running just the code from MDN in a node console worked fine however, so I suspect the environment is OK, but I'm missing the use case.

@observable timer = 0; is observable object property, not boxed primitive. The observable property is "unwrapped" in getter created by MobX, so it works just fine.

However, I meant this:

let number = mobx.observable(5);
console.log(number); // ObservableValue
console.log(number++); // NaN
console.log(number + 7); // NaN

I am sorry for not being specific enough.

Thanks for the clarification. I think you were specific enough but I am a noob in mobx ;)

Using your example and the change I already wrote above, I get this result:

ObservableValue {
  name: 'ObservableValue@1',
  isPendingUnobservation: true,
  observers: [],
  observersIndexes: {},
  diffValue: 0,
  lastAccessedBy: 0,
  lowestObserverState: -1,
  mode: 0,
  hasUnreportedChange: false,
  value: 5 }
5
13

I think this exactly what you were expecting, isn't it?

However, the simple change I outlined in the above comment has some issues:

  • console.log(number++); results in TypeScript error TS2356: An arithmetic operand must be of type 'any', 'number' or an enum type.
  • console.log(number + 7); results in TypeScript error TS2365: Operator '+' cannot be applied to types 'IObservableValue' and 'number'.

With some more TypeScript magic added, maybe you could make it work without warnings. However looking at https://github.com/Microsoft/TypeScript/issues/2361 there will be more challenges to make that happen.

I am actually not sure about console.log(number);, I quess it would depend on console.log implementation, which is not standardized afaik.
I don't know TypeScript so I can't really comment on that one.
In case of JS, support for Symbol.toPrimitive should be available on V8 version >= 4.8, that's node >= 6.0 .
For browser support, Babel seems working fine.

I would love to give this a shot. 馃憤

Released as part of 3.0.2. Thanks for the PR @eladnava !

Was this page helpful?
0 / 5 - 0 ratings