Skip to content

Commit

Permalink
Add warning about automatic computed conversion, see #421 / #532
Browse files Browse the repository at this point in the history
  • Loading branch information
mweststrate committed Dec 7, 2016
1 parent c3d0ce4 commit 85ffdf2
Showing 1 changed file with 24 additions and 8 deletions.
32 changes: 24 additions & 8 deletions src/types/observableobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@ import {ObservableValue, UNCHANGED} from "./observablevalue";
import {isComputedValue, ComputedValue} from "../core/computedvalue";
import {isAction} from "../api/action";
import {ValueMode, getModifier} from "./modifiers";
import {createInstanceofPredicate, isObject, Lambda, getNextId, invariant, assertPropertyConfigurable, isPlainObject, addHiddenFinalProp} from "../utils/utils";
import {createInstanceofPredicate, isObject, Lambda, getNextId, invariant, assertPropertyConfigurable, isPlainObject, addHiddenFinalProp, deprecated} from "../utils/utils";
import {runLazyInitializers} from "../utils/decorators";
import {hasInterceptors, IInterceptable, registerInterceptor, interceptChange} from "./intercept-utils";
import {IListenable, registerListener, hasListeners, notifyListeners} from "./listen-utils";
import {isSpyEnabled, spyReportStart, spyReportEnd} from "../core/spy";

const COMPUTED_FUNC_DEPRECATED = (
`
In MobX 2.* passing a function without arguments to (extend)observable will automatically be inferred to be a computed value.
This behavior is ambiguous and will change in MobX 3 to create just an observable reference to the value passed in.
To disambiguate, please pass the function wrapped with a modifier: use 'computed(fn)' (for current behavior; automatic conversion), or 'asReference(fn)' (future behavior, just store reference) or 'action(fn)'.
Note that the idiomatic way to write computed properties is 'observable({ get propertyName() { ... }})'.
For more details, see https://github.com/mobxjs/mobx/issues/532`);

export interface IObservableObject {
"observable-object": IObservableObject;
}
Expand Down Expand Up @@ -60,7 +68,7 @@ export function asObservableObject(target, name: string, mode: ValueMode = Value
return target.$mobx;

if (!isPlainObject(target))
name = target.constructor.name + "@" + getNextId();
name = (target.constructor.name || "ObservableObject") + "@" + getNextId();
if (!name)
name = "ObservableObject@" + getNextId();

Expand All @@ -69,15 +77,24 @@ export function asObservableObject(target, name: string, mode: ValueMode = Value
return adm;
}

function handleAsComputedValue(value): boolean {
return typeof value === "function" && value.length === 0 && !isAction(value)
}

export function setObservableObjectInstanceProperty(adm: ObservableObjectAdministration, propName: string, descriptor: PropertyDescriptor) {
if (adm.values[propName]) {
invariant("value" in descriptor, "cannot redefine property " + propName);
adm.target[propName] = descriptor.value; // the property setter will make 'value' reactive if needed.
} else {
if ("value" in descriptor)
if ("value" in descriptor) {
if (handleAsComputedValue(descriptor.value)) {
// warn about automatic inference, see https://github.com/mobxjs/mobx/issues/421
deprecated(`${COMPUTED_FUNC_DEPRECATED})in: ${adm.name}.${propName}`);
}
defineObservableProperty(adm, propName, descriptor.value, true, undefined);
else
} else {
defineObservableProperty(adm, propName, descriptor.get, true, descriptor.set);
}
}
}

Expand All @@ -90,15 +107,14 @@ export function defineObservableProperty(adm: ObservableObjectAdministration, pr
let isComputed = true;

if (isComputedValue(newValue)) {
// desugger computed(getter, setter)
// TODO: deprecate this and remove in 3.0, to keep them boxed
// desugar computed(getter, setter)
// TODO: deprecate this and remove in 3.0, to keep them boxed?
// get / set is now the idiomatic syntax for non-boxed computed values
observable = newValue;
newValue.name = name;
if (!newValue.scope)
newValue.scope = adm.target;
} else if (typeof newValue === "function" && newValue.length === 0 && !isAction(newValue)) {
// TODO: add warning in 2.6, see https://github.com/mobxjs/mobx/issues/421
} else if (handleAsComputedValue(newValue)) {
// TODO: remove in 3.0
observable = new ComputedValue(newValue, adm.target, false, name, setter);
} else if (getModifier(newValue) === ValueMode.Structure && typeof newValue.value === "function" && newValue.value.length === 0) {
Expand Down

0 comments on commit 85ffdf2

Please sign in to comment.