Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not use JSON stringify/parse functions in Helpers.getUnbindValue f… #6479

Merged
merged 1 commit into from
Jul 5, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions src/helpers.ts
Original file line number Diff line number Diff line change
@@ -162,13 +162,27 @@ export class Helpers {
return array;
}
public static getUnbindValue(value: any): any {
Copy link

@salargl salargl Jul 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @andrewtelnov thanks for the fix. But I wonder what this function tries to achieve? and what happens if we just return the value when it is an instance of Array e.g.:

public static getUnbindValue(value: any): any {
  if(Array.isArray(value)) {
    return value;
  }
  if (!!value && value instanceof Object && !(value instanceof Date)) {
    const res: any = {};
    const keys = Object.keys(value);
    keys.forEach(key => {
      const val = Helpers.getUnbindValue(value[key]);
      if(val !== undefined) {
        res[key] = val;
      }
    });
    return res;
  }
  return value;
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@salargl If you run unit tests with your code then 68 unit tests will be failed.
Here is the reason:

const val = matrixQustion.value;
val.push(newValue); //this line will modify matrixQustion.value becaue the instance is the same.

I had to modify the code to the following to fix unit tests in SurveyJS Creator V1&V2:

  public static getUnbindValue(value: any): any {
    if(Array.isArray(value)) {
      const res = [];
      for(let i = 0; i < value.length; i ++) {
        res.push(Helpers.getUnbindValue(value[i]));
      }
      return res;
    }
    if (!!value && value instanceof Object && !(value instanceof Date)) {
      return JSON.parse(JSON.stringify(value));
    }
    return value;
  }

Thank you,
Andrew

if(Array.isArray(value)) {
const res = [];
for(let i = 0; i < value.length; i ++) {
res.push(Helpers.getUnbindValue(value[i]));
}
return res;
}
if (!!value && value instanceof Object && !(value instanceof Date)) {
//do not return the same object instance!!!
return JSON.parse(JSON.stringify(value));
const res: any = {};
const keys = Object.keys(value);
keys.forEach(key => {
const val = Helpers.getUnbindValue(value[key]);
if(val !== undefined) {
res[key] = val;
}
});
return res;
}
return value;
}
public static createCopy(obj: any) {
public static createCopy(obj: any): any {
var res: any = {};
if (!obj) return res;
for (var key in obj) {
5 changes: 5 additions & 0 deletions tests/helperstests.ts
Original file line number Diff line number Diff line change
@@ -460,6 +460,11 @@ QUnit.test("getUnbindValue function", function(assert) {
assert.deepEqual(obj, unbindObj, "objects are deep equal");
const dateVal = new Date(2004, 5, 7);
assert.strictEqual(Helpers.getUnbindValue(dateVal), dateVal, "do not convert date");
const arr = [1, "abc", { val: 1 }];
const unbindArr = Helpers.getUnbindValue(arr);
assert.notStrictEqual(arr, unbindArr, "new array are not strict equal");
assert.notStrictEqual(arr[2], unbindArr[2], "nested object in new array are not strict equal");
assert.deepEqual(arr, unbindArr, "Arrays are equals");
});
QUnit.test("convertDateToString/convertDateTimeToString functions", function(assert) {
const d = new Date(2022, 11, 24, 10, 55, 33, 3);