Skip to content

Commit

Permalink
Merge branch 'master' into whyrun
Browse files Browse the repository at this point in the history
  • Loading branch information
mweststrate committed Jun 13, 2016
2 parents f9a236c + e03dc43 commit 27712fd
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* `@observable` is now always defined on the class and not in the instances. This means that `@observable` properties are enumerable, but won't appear if `Object.keys` or `hasOwnProperty` is used on a class _instance_.
* if an (argumentless) action is passed to `observable` / `extendObservable`, it will not be converted into a computed property.
* Implemented #316: `whyRun()`
* Fixed #285: class instances are now also converted by `toJS`. Also members defined on prototypes which are enumerable are converted.

# 2.2.2:

Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ _Simple, scalable state management_
[![Build Status](https://travis-ci.org/mobxjs/mobx.svg?branch=master)](https://travis-ci.org/mobxjs/mobx)
[![Coverage Status](https://coveralls.io/repos/mobxjs/mobx/badge.svg?branch=master&service=github)](https://coveralls.io/github/mobxjs/mobx?branch=master)
[![Join the chat at https://gitter.im/mobxjs/mobx](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mobxjs/mobx?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![#mobx channel on reactiflux discord](https://img.shields.io/badge/discord-%23mobx%20%40reactiflux-blue.svg)](https://discord.gg/0ZcbPKXt5bYAa2J1)

* Installation: `npm install mobx --save`. React bindings: `npm install mobx-react --save`
* [Ten minute, interactive MobX + React tutorial](https://mobxjs.github.io/mobx/getting-started.html)
Expand All @@ -27,7 +26,7 @@ _Anything that can be derived from the application state, should be derived. Aut

which includes the UI, data serialization, server communication, etc.

<img alt="MobX unidirectional flow" src="docs/flow.png" height="200" align="center" />
<img alt="MobX unidirectional flow" src="docs/flow.png" align="center" />

React and MobX together are a powerful combination. React renders the application state by providing mechanisms to translate it into a tree of renderable components. MobX provides the mechanism to store and update the application state that React then uses.

Expand Down
10 changes: 6 additions & 4 deletions src/api/tojson.ts → src/api/tojs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,16 @@ export function toJS(source, detectCycles: boolean = true, __alreadySeen: [any,
);
return res;
}
if (typeof source === "object" && isPlainObject(source)) {
if (isObservable(source) && source.$mobx instanceof ObservableValue)
return toJS(source(), detectCycles, __alreadySeen);
if (source instanceof ObservableValue)
return toJS(source.get(), detectCycles, __alreadySeen);
if (typeof source === "object") {
const res = cache({});
for (let key in source) if (source.hasOwnProperty(key))
for (let key in source)
res[key] = toJS(source[key], detectCycles, __alreadySeen);
return res;
}
if (isObservable(source) && source.$mobx instanceof ObservableValue)
return toJS(source(), detectCycles, __alreadySeen);
return source;
}

Expand Down
2 changes: 1 addition & 1 deletion src/mobx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export { observe } from "./api/obse
export { intercept } from "./api/intercept";
export { autorun, autorunAsync, autorunUntil, when, reaction } from "./api/autorun";
export { expr } from "./api/expr";
export { toJSON, toJS } from "./api/tojson";
export { toJSON, toJS } from "./api/tojs";
export { ITransformer, createTransformer } from "./api/createtransformer";
export { whyRun } from "./api/whyrun";

Expand Down
25 changes: 25 additions & 0 deletions test/babel/babel-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -523,3 +523,28 @@ test("enumerability", t => {

t.end();
})

test("issue 285 (babel)", t => {
const {observable, toJS} = mobx;

class Todo {
id = 1;
@observable title;
@observable finished = false;
@observable childThings = [1,2,3];
constructor(title) {
this.title = title;
}
}

var todo = new Todo("Something to do");

t.deepEqual(toJS(todo), {
id: 1,
title: "Something to do",
finished: false,
childThings: [1,2,3]
})

t.end();
})
52 changes: 52 additions & 0 deletions test/observables.js
Original file line number Diff line number Diff line change
Expand Up @@ -1099,6 +1099,58 @@ test('json cycles', function(t) {
t.end();
})

test('#285 class instances with toJS', t => {
function Person() {
this.firstName = "michel";
mobx.extendObservable(this, {
lastName: "weststrate",
tags: ["user", "mobx-member"],
fullName: function() {
return this.firstName + this.lastName
}
})
}

const p1 = new Person();
// check before lazy initialization
t.deepEqual(mobx.toJS(p1), {
firstName: "michel",
lastName: "weststrate",
tags: ["user", "mobx-member"]
});

// check after lazy initialization
t.deepEqual(mobx.toJS(p1), {
firstName: "michel",
lastName: "weststrate",
tags: ["user", "mobx-member"]
});

t.end()
})

test('#285 non-mobx class instances with toJS', t => {
function Person() {
this.firstName = "michel";
this.lastName = mobx.observable("weststrate");
}

const p1 = new Person();
// check before lazy initialization
t.deepEqual(mobx.toJS(p1), {
firstName: "michel",
lastName: "weststrate"
});

// check after lazy initialization
t.deepEqual(mobx.toJS(p1), {
firstName: "michel",
lastName: "weststrate"
});

t.end()
})

function stripSpyOutput(events) {
events.forEach(ev => {
delete ev.time;
Expand Down
24 changes: 24 additions & 0 deletions test/typescript-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -796,3 +796,27 @@ test("enumerability", t => {
t.end();
})

test("issue 285 (babel)", t => {
const {observable, toJS} = mobx;

class Todo {
id = 1;
@observable title: string;
@observable finished = false;
@observable childThings = [1,2,3];
constructor(title: string) {
this.title = title;
}
}

var todo = new Todo("Something to do");

t.deepEqual(toJS(todo), {
id: 1,
title: "Something to do",
finished: false,
childThings: [1,2,3]
})

t.end();
})

0 comments on commit 27712fd

Please sign in to comment.