Description
Describe the bug
I am currently using surveyjs within a react app. I have a custom function that returns an uuid value and I invoke that function using an expression in the surveyjs JSON. Now, I have observed the following.
This uuid() has no parameter input, yet whenever I select any value from any other dropdown of any other field in the form that has no dependency with the uuid expression field, then also the uuid value of the expression gets updated - unnecessarily and this also causes a re-render.
If I have a function with a parameter input, this parameter input comes from a particular field of the survey. Now even if I alter another field that is not related to the parameter input of this expression custom function, then also expression gets re-evaluated, and the function is re-invoked. This also causes an unnecessary re-render.
Considering the obs#2, if I put the mentioned function with single param input within an iif() statement, such that the function should only be invoked if the condition is true, then also the expression containing the function gets evaluated even though the condition is false. This is preventing me from restricting a custom function call via iif statement.
Consider this example for understanding the scenario better.
Steps to reproduce
{
"type": "expression",
"name": "audit_id",
"expression": "uuid()"
},
{
"type": "dropdown",
"name": "audit_type",
"choices": ["audit-type1", "audit-type2"]
},
{
"type": "dropdown",
"name": "model",
"choices": ["model1", "model2"]
},
{
"type": "expression",
"name": "service",
"expression": "iif({enable_model} == true, findServiceByModel({model})), 'null'"
},
{
"type": "boolean",
"name": "enable_model",
"valueTrue": "true",
"valueFalse": "false"
}
Expected behavior
Note: findServiceByModel() is already registered in a FunctionFactory instance and async in nature.
In this example
audit_id get re-evaluated each time I change audit_type dropdown value.
findServiceByModel() will get invoked even if I change audit_type which is completely independant.
findServiceByModel() will get invoked even if enable_model is set to false.
Ideally, expressions should only be re-evaluated if its dependent param changes else not.
Please let me know how the above concerns can be addressed in surveyjs.
Evidence
Stacktrace evidence:
App.js:182 No parameters received
overrideMethod @ hook.js:608
findOCRService @ App.js:182
FunctionFactory.run @ functionsfactory.ts:60
FunctionOperand.evaluateCore @ expressions.ts:382
FunctionOperand.evaluate @ expressions.ts:367
ExpressionExecutorRunner.runAsyncItemCore @ conditions.ts:86
ExpressionExecutorRunner.runAsyncItem @ conditions.ts:81
(anonymous) @ conditions.ts:79
ExpressionExecutorRunner.runAsyncItem @ conditions.ts:79
ExpressionExecutorRunner.run @ conditions.ts:64
ExpressionExecutor.run @ conditions.ts:173
ExpressionRunnerBase.runCore @ conditions.ts:225
ExpressionRunner.run @ conditions.ts:248
QuestionExpressionModel.runCondition @ question_expression.ts:77
PanelModelBase.runCondition @ panel.ts:1934
QuestionCompositeModel.runCondition @ question_custom.ts:1206
PanelModelBase.runCondition @ panel.ts:1934
PanelModelBase.runCondition @ panel.ts:1934
QuestionPanelDynamicModel.runPanelsCondition @ question_paneldynamic.ts:1890
QuestionPanelDynamicModel.runCondition @ question_paneldynamic.ts:1856
PanelModelBase.runCondition @ panel.ts:1934
SurveyModel.runConditionsCore @ survey.ts:6124
SurveyModel.runConditions @ survey.ts:6070
SurveyModel.runConditionOnValueChanged @ survey.ts:6105
SurveyModel.checkTriggersAndRunConditions @ survey.ts:6032
SurveyModel.updateOnSetValue @ survey.ts:6720
SurveyModel.setValue @ survey.ts:6695
Question.setValueCore @ question.ts:2407
QuestionPanelDynamicModel.setValueCore @ question_paneldynamic.ts:910
Question.setNewValueInData @ question.ts:2397
Question.setNewValue @ question.ts:2354
set @ question.ts:1629
QuestionPanelDynamicModel.setPanelItemData @ question_paneldynamic.ts:2284
QuestionPanelDynamicItem.setValue @ question_paneldynamic.ts:158
Question.setValueCore @ question.ts:2407
QuestionSelectBase.setValueCore @ question_baseselect.ts:672
Question.setNewValueInData @ question.ts:2397
Question.setNewValue @ question.ts:2354
QuestionSelectBase.setNewValue @ question_baseselect.ts:687
set @ question.ts:1629
_onSelectionChanged @ dropdownListModel.ts:221
ListModel._this.onItemClick @ list.ts:211
onClick @ list-item.tsx:53
Please complete the following information:
- Browser: MS Edge
- Browser version: latest
- JS framework/library: React,
- SurveyJS version: latest
- Device: PC
Additional context
https://stackoverflow.com/questions/79299024/how-to-restrict-re-evaluation-of-expressions-for-only-those-change-in-values-on