Skip to content

Commit

Permalink
Merge pull request #7255 from surveyjs/bug/7254-json-parser-object-to…
Browse files Browse the repository at this point in the history
…-array

Allow to parse with json error on setting an object to an array prope…
  • Loading branch information
andrewtelnov authored Oct 30, 2023
2 parents 1b7f3d4 + 3fd8f55 commit 61ba14c
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 10 deletions.
18 changes: 16 additions & 2 deletions src/jsonobject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,10 @@ export class JsonMetadataClass {
}
if (propInfo.baseClassName) {
prop.baseClassName = propInfo.baseClassName;
prop.isArray = true;
}
if(prop.isArray === true) {
prop.isArray = true;
}
if (propInfo.classNamePart) {
prop.classNamePart = propInfo.classNamePart;
Expand Down Expand Up @@ -1482,6 +1486,11 @@ export class JsonRequiredPropertyError extends JsonError {
);
}
}
export class JsonRequiredArrayPropertyError extends JsonError {
constructor(public propertyName: string, public className: string) {
super("arrayproperty", "The property '" + propertyName + "' should be an array in '" + className + "'.");
}
}

export class JsonObject {
private static typePropertyName = "type";
Expand Down Expand Up @@ -1531,7 +1540,7 @@ export class JsonObject {
}
continue;
}
this.valueToObj(jsonObj[key], obj, property);
this.valueToObj(jsonObj[key], obj, property, jsonObj);
}
if (obj.endLoadingFromJson) {
obj.endLoadingFromJson();
Expand Down Expand Up @@ -1629,13 +1638,18 @@ export class JsonObject {
}
}
}
public valueToObj(value: any, obj: any, property: JsonObjectProperty) {
public valueToObj(value: any, obj: any, property: JsonObjectProperty, jsonObj?: any): void {
if (value === null || value === undefined) return;
this.removePos(property, value);
if (property != null && property.hasToUseSetValue) {
property.setValue(obj, value, this);
return;
}
if(property.isArray && !Array.isArray(value) && !!value) {
value = [value];
const propName = !!jsonObj && property.alternativeName && !!jsonObj[property.alternativeName] ? property.alternativeName : property.name;
this.addNewError(new JsonRequiredArrayPropertyError(propName, obj.getType()), !!jsonObj ? jsonObj: value, obj);
}
if (this.isValueArray(value)) {
this.valueToArray(value, obj, property.name, property);
return;
Expand Down
2 changes: 1 addition & 1 deletion src/question_matrixdropdownbase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2440,7 +2440,7 @@ Serializer.addClass(
[
{
name: "columns:matrixdropdowncolumns",
className: "matrixdropdowncolumn",
className: "matrixdropdowncolumn", isArray: true
},
{
name: "columnLayout",
Expand Down
2 changes: 1 addition & 1 deletion src/question_multipletext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ Serializer.addClass(
Serializer.addClass(
"multipletext",
[
{ name: "!items:textitems", className: "multipletextitem" },
{ name: "!items:textitems", className: "multipletextitem", isArray: true },
{ name: "itemSize:number", minValue: 0 },
{ name: "colCount:number", default: 1, choices: [1, 2, 3, 4, 5] },
{ name: "itemErrorLocation", default: "default", choices: ["default", "top", "bottom"], visible: false }
Expand Down
12 changes: 6 additions & 6 deletions src/survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7480,13 +7480,13 @@ Serializer.addClass("survey", [
},
{
name: "completedHtmlOnCondition:htmlconditions",
className: "htmlconditionitem",
className: "htmlconditionitem", isArray: true
},
{ name: "loadingHtml:html", serializationProperty: "locLoadingHtml" },
{ name: "pages:surveypages", className: "page" },
{ name: "pages:surveypages", className: "page", isArray: true },
{
name: "questions",
alternativeName: "elements",
name: "elements",
alternativeName: "questions",
baseClassName: "question",
visible: false,
isLightSerializable: false,
Expand All @@ -7506,7 +7506,7 @@ Serializer.addClass("survey", [
},
{
name: "calculatedValues:calculatedvalues",
className: "calculatedvalue",
className: "calculatedvalue", isArray: true
},
{ name: "surveyId", visible: false },
{ name: "surveyPostId", visible: false },
Expand All @@ -7525,7 +7525,7 @@ Serializer.addClass("survey", [
"navigateToUrl",
{
name: "navigateToUrlOnCondition:urlconditions",
className: "urlconditionitem",
className: "urlconditionitem", isArray: true
},
{
name: "questionsOrder",
Expand Down
41 changes: 41 additions & 0 deletions tests/jsonobjecttests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3032,4 +3032,45 @@ QUnit.test("Check that .toJSON returns clean structure for all question types",
}
}
}
});
QUnit.test("Add a quesition into page elements array", function (assert) {
const prop = Serializer.findProperty("page", "elements");
assert.equal(prop.isArray, true, "Elements is an array");
const survey = new SurveyModel({
pages: [
{
elements: { type: "text", name: "q1" }
}
]
});
assert.equal(survey.pages.length, 1, "There is one page");
assert.equal(survey.pages[0].elements.length, 1, "There is one element in the page");
assert.equal(survey.pages[0].elements[0].name, "q1", "Element has a correct name");
assert.equal(survey.jsonErrors.length, 1, "There is a JSON error");
assert.equal((<any>survey.jsonErrors[0]).propertyName, "elements", "Correct property name");
});
QUnit.test("Add a quesition into survey questions array", function (assert) {
const prop = Serializer.findProperty("survey", "elements");
assert.equal(prop.isArray, true, "Elements is an array");
const survey = new SurveyModel({
questions: { type: "text", name: "q1" }
});
assert.equal(survey.pages.length, 1, "There is one page");
assert.equal(survey.pages[0].elements.length, 1, "There is one element in the page");
assert.equal(survey.pages[0].elements[0].name, "q1", "Element has a correct name");
assert.equal(survey.jsonErrors.length, 1, "There is a JSON error");
assert.equal((<any>survey.jsonErrors[0]).propertyName, "questions", "Correct property name");
});
QUnit.test("Add a page into survey pages array", function (assert) {
const prop = Serializer.findProperty("survey", "pages");
assert.equal(prop.isArray, true, "Elements is an array");
const survey = new SurveyModel({
pages: { questions: { type: "text", name: "q1" } }
});
assert.equal(survey.pages.length, 1, "There is one page");
assert.equal(survey.pages[0].elements.length, 1, "There is one element in the page");
assert.equal(survey.pages[0].elements[0].name, "q1", "Element has a correct name");
assert.equal(survey.jsonErrors.length, 2, "There are JSONs error");
assert.equal((<any>survey.jsonErrors[0]).propertyName, "pages", "Correct property name #1");
assert.equal((<any>survey.jsonErrors[1]).propertyName, "questions", "Correct property name #2");
});

0 comments on commit 61ba14c

Please sign in to comment.