fromObjectRecursive internally calls addPropertiesFromObject with recursive=true. The internal function mutates the source (see source[prop]= )without any sort of advertising it in the docs.
function addPropertiesFromObject(observable: ObservableFromObject, source: any, recursive: boolean = false) {
let isRecursive = recursive;
for (let prop in source) {
if (source.hasOwnProperty(prop)) {
if (isRecursive) {
if (!Array.isArray(source[prop]) && source[prop] && typeof source[prop] === 'object' && !(source[prop] instanceof Observable)) {
source[prop] = fromObjectRecursive(source[prop]);
}
}
defineNewProperty(observable, prop);
observable.set(prop, source[prop]);
}
}
}
@sserdyuk the difference in fromObject and fromObjectRecursive is that the second one iterates recursively your object and creates Observable objects from any nested Object type properties.
e.g.
var obj = {
"id": 1,
"info" : {
"name" : "John"
}
}
let observableObject = fromObject(obj);
console.dir(observableObject);
// will print
/*
JS: === dump(): dumping members ===
JS: {
JS: "_observers": {},
JS: "_map": {
JS: "id": 1,
JS: "info": {
JS: "name": "John"
JS: }
JS: },
JS: "id": 1,
JS: "info": "#CR:[object Object]"
JS: }
JS: === dump(): dumping function and properties names ===
*/
let observableObjectRecursive= fromObjectRecursive(obj);
console.dir(observableObjectRecursive);
// will print
JS: === dump(): dumping members ===
JS: {
JS: "_observers": {},
JS: "_map": {
JS: "id": 1,
JS: "info": {
JS: "_observers": {},
JS: "_map": {
JS: "name": "John"
JS: },
JS: "name": "John"
JS: }
JS: },
JS: "id": 1,
JS: "info": "#CR:[object Object]"
JS: }
JS: === dump(): dumping function and properties names ===
@NickIliev It's not a question, it's a bug report. Two bugs: it mutates the source object, and having been called twice, it internally returns same object. Both behaviors are unexpected.
const source = { a: 1, b: { c: 2 } };
console.log('source.b before is POJO');
console.dir(source.b);
const obs1 = fromObjectRecursive(source);
console.log('source.b after is ObservableFromObject');
console.dir(source.b);
const obs2 = fromObjectRecursive(source);
console.log('obs2 b.c is : '+ obs2.get('b').get('c'));
obs1.get('b').set('c', 3);
console.log('obs2 b.c: should be 2 but is '+ obs2.get('b').get('c'));
JS: source.b before is POJO
JS: === dump(): dumping members ===
JS: {
JS: "c": 2
JS: }
JS: === dump(): dumping function and properties names ===
JS: === dump(): finished ===
JS: source.b after is ObservableFromObject
JS: === dump(): dumping members ===
JS: {
JS: "_observers": {},
JS: "_map": {
JS: "c": 2
JS: },
JS: "c": 2
JS: }
JS: === dump(): dumping function and properties names ===
JS: constructor()
JS: get()
JS: set()
JS: on()
JS: off()
JS: addEventListener()
JS: removeEventListener()
JS: notify()
JS: notifyPropertyChange()
JS: hasListeners()
JS: _createPropertyChangeData()
JS: _emit()
JS: _getEventList()
JS: _indexOfListener()
JS: === dump(): finished ===
JS: obs2 b.c is : 2
JS: obs2 b.c: should be 2 but is 3
Yes it is a bug. It obviously mutates both the source and the observable arguments. IMO it should always do full clones.
@sserdyuk thank you for clarifying the issue - confirming this as a bug.
Steps to reproduce: use this test application.
Fix included in https://github.com/NativeScript/NativeScript/tree/hhristov/nested-frames - will be included in the upcoming release
Confirming as resolved with tns-core-modules@next and this demo applicaiton
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.