Skip to content

Commit 3fc7069

Browse files
author
Nedyalko Nikolov
committed
Fixed creating Observable object from nested JSON object.
1 parent a736bc0 commit 3fc7069

File tree

4 files changed

+51
-11
lines changed

4 files changed

+51
-11
lines changed

tests/app/data/observable-tests.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import dependencyObservable = require("ui/core/dependency-observable");
66
import TKUnit = require("../TKUnit");
77
import types = require("utils/types");
88
import proxy = require("ui/core/proxy");
9+
import {ObservableArray} from "data/observable-array";
910

1011
var TESTED_NAME = "tested";
1112
class TestObservable extends observable.Observable {
@@ -525,3 +526,12 @@ export function test_CorrectPropertyValueAfterUsingWrappedValue() {
525526

526527
TKUnit.assertEqual(testObservable.get("property1"), testArray, "WrappedValue is used only to execute property change logic and unwrapped value should be used as proeprty value.");
527528
}
529+
530+
export function test_NestedObservablesWithObservableArrayShouldNotCrash() {
531+
let someObservableArray = new ObservableArray<any>();
532+
let testObservable = observable.Observable.fromJSONRecursive({
533+
firstProp: "test string",
534+
secondProp: someObservableArray
535+
});
536+
TKUnit.assert(testObservable !== undefined);
537+
}

tests/app/ui/bindable-tests.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,7 +1265,7 @@ export function test_only_Bindable_BindingContext_Null_DoesNotThrow() {
12651265

12661266
export function test_Observable_from_nested_json_binds_correctly() {
12671267
let expectedValue = "Test";
1268-
var model = new observable.Observable({
1268+
let model = observable.Observable.fromJSONRecursive({
12691269
"firstObject": {
12701270
"secondObject": {
12711271
"dummyProperty": "text"
@@ -1286,7 +1286,7 @@ export function test_Observable_from_nested_json_binds_correctly() {
12861286

12871287
export function test_Observable_from_nested_json_binds_correctly_when_upper_object_is_changed() {
12881288
let expectedValue = "Test";
1289-
var model = new observable.Observable({
1289+
let model = observable.Observable.fromJSONRecursive({
12901290
"firstObject": {
12911291
"secondObject": {
12921292
"dummyProperty": "text"

tns-core-modules/data/observable/observable.d.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,19 @@ declare module "data/observable" {
7070
*/
7171
public static propertyChangeEvent: string;
7272

73+
/**
74+
* Creates an Observable instance and sets its properties according to the supplied JSON object.
75+
*/
76+
public static fromJSON(json: any): Observable;
77+
7378
/**
7479
* Creates an Observable instance and sets its properties according to the supplied JSON object.
80+
* This function will create new Observable for each nested object (expect arrays and functions) from supplied JSON.
81+
*/
82+
public static fromJSONRecursive(json: any): Observable;
83+
84+
/**
85+
* [Deprecated please use static functions fromJSON or fromJSONRecursive instead] Creates an Observable instance and sets its properties according to the supplied JSON object.
7586
*/
7687
constructor(json?: any);
7788

tns-core-modules/data/observable/observable.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,40 @@ export class Observable implements definition.Observable {
5151

5252
private _observers = {};
5353

54-
constructor(json?: any) {
55-
if (json) {
56-
this._map = new Map<string, Object>();
57-
for (var prop in json) {
58-
if (json.hasOwnProperty(prop)) {
59-
if (!Array.isArray(json[prop]) && typeof json[prop] === 'object') {
60-
json[prop] = new Observable(json[prop]);
54+
public static fromJSON(json: any): Observable {
55+
let observable = new Observable();
56+
observable.addPropertiesFromJSON(observable, json, false);
57+
return observable;
58+
}
59+
60+
public static fromJSONRecursive(json: any): Observable {
61+
let observable = new Observable();
62+
observable.addPropertiesFromJSON(observable, json, true);
63+
return observable;
64+
}
65+
66+
private addPropertiesFromJSON(observable: Observable, json: any, recursive?: boolean) {
67+
let isRecursive = recursive || false;
68+
observable._map = new Map<string, Object>();
69+
for (var prop in json) {
70+
if (json.hasOwnProperty(prop)) {
71+
if (isRecursive) {
72+
if (!Array.isArray(json[prop]) && typeof json[prop] === 'object' && types.getClass(json[prop]) !== 'ObservableArray') {
73+
json[prop] = Observable.fromJSONRecursive(json[prop]);
6174
}
62-
this._defineNewProperty(prop);
63-
this.set(prop, json[prop]);
6475
}
76+
observable._defineNewProperty(prop);
77+
observable.set(prop, json[prop]);
6578
}
6679
}
6780
}
6881

82+
constructor(json?: any) {
83+
if (json) {
84+
this.addPropertiesFromJSON(this, json);
85+
}
86+
}
87+
6988
private _defineNewProperty(propertyName: string): void {
7089
Object.defineProperty(this, propertyName, {
7190
get: function () {

0 commit comments

Comments
 (0)