Skip to content

Commit 38ae03b

Browse files
authored
fix: Updating logic for reactive actions to fix cyclic dependency issue with App templates and Generate page flow of a DB (#41144)
## Description Updating logic for reactive actions to fix cyclic dependency issue with App templates and Generate page flow of a DB. Currently, both flows were leading to cyclic dependency errors which shouldn't show up. App template used - Order Fulfilment Tracker DB used - Mock DB Movies Fixes [#41125](#41125) [41113](#41113) EE PR for tests: https://github.com/appsmithorg/appsmith-ee/pull/8029 ## Automation /ok-to-test tags="@tag.All" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/16590882275> > Commit: 9079357 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=16590882275&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.All` > Spec: > <hr>Tue, 29 Jul 2025 09:46:35 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Summary by CodeRabbit * **Refactor** * Improved dependency detection logic for actions and JS actions, refining how data paths are identified and handled. * Unified data path detection by using a shared utility function across the application. * Enhanced filtering of entities during dependency calculations for greater accuracy. * **Bug Fixes** * Corrected detection of reactive dependency misuse to reduce false positives for certain entity types. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 9930224 commit 38ae03b

3 files changed

Lines changed: 40 additions & 37 deletions

File tree

app/client/src/ce/workers/Evaluation/evaluationUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ export function getExternalChangedDependencies(
11971197
}
11981198

11991199
export const isDataPath = (
1200-
entity: DataTreeEntity,
1200+
entity: DataTreeEntity | Partial<DataTreeEntityConfig>,
12011201
fullPropertyPath: string,
12021202
) => {
12031203
if (isWidget(entity)) {

app/client/src/ce/workers/common/DependencyMap/utils/getEntityDependenciesByType.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,6 @@ export function getJSDependencies(
132132
dependencies = { ...dependencies, [fullPropertyPath]: newDeps };
133133
}
134134

135-
for (const funcName of jsActionConfig.actionNames) {
136-
const func = jsEntity[funcName];
137-
138-
if (func) {
139-
dependencies[`${jsObjectName}.${funcName}.data`] = [
140-
`${jsObjectName}.${funcName}`,
141-
];
142-
}
143-
}
144-
145135
return dependencies;
146136
}
147137
export function getActionDependencies(

app/client/src/entities/DependencyMap/DependencyMapUtils.ts

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import {
55
getEntityNameAndPropertyPath,
66
IMMEDIATE_PARENT_REGEX,
77
isActionConfig,
8+
isDataPath,
89
isJSActionConfig,
10+
isWidget,
911
} from "ee/workers/Evaluation/evaluationUtils";
1012
import type { ConfigTree } from "entities/DataTree/dataTreeTypes";
1113
import { isPathDynamicTrigger } from "utils/DynamicBindingUtils";
@@ -167,10 +169,6 @@ export class DependencyMapUtils {
167169
return false;
168170
}
169171

170-
static isDataPath(path: string) {
171-
return path.endsWith(".data");
172-
}
173-
174172
static detectReactiveDependencyMisuse(
175173
dependencyMap: DependencyMap,
176174
configTree: ConfigTree,
@@ -213,27 +211,34 @@ export class DependencyMapUtils {
213211
);
214212

215213
for (const dep of transitiveDeps) {
216-
if (this.isTriggerPath(dep, configTree)) {
217-
hasRun = true;
218-
runPath = dep;
219-
}
220-
221-
if (this.isDataPath(dep)) {
222-
hasData = true;
223-
dataPath = dep;
224-
}
225-
226-
if (
227-
hasRun &&
228-
hasData &&
229-
runPath.split(".")[0] === dataPath.split(".")[0]
230-
) {
231-
throw Object.assign(
232-
new Error(
233-
`Reactive dependency misuse: '${node}' depends on both trigger path '${runPath}' and data path '${dataPath}' from the same entity. This can cause unexpected reactivity.`,
234-
),
235-
{ node, triggerPath: runPath, dataPath },
236-
);
214+
const { entityName: depName } = getEntityNameAndPropertyPath(dep);
215+
const entity = configTree[depName];
216+
217+
// to show cyclic dependency errors only for Action calls and not JSObject.body or JSObject
218+
if (entity && entity.ENTITY_TYPE) {
219+
if (this.isTriggerPath(dep, configTree)) {
220+
hasRun = true;
221+
runPath = dep;
222+
}
223+
224+
// using the isDataPath function from evalUtils to calculate data paths based on entity type
225+
if (isDataPath(entity, dep)) {
226+
hasData = true;
227+
dataPath = dep;
228+
}
229+
230+
if (
231+
hasRun &&
232+
hasData &&
233+
runPath.split(".")[0] === dataPath.split(".")[0]
234+
) {
235+
throw Object.assign(
236+
new Error(
237+
`Reactive dependency misuse: '${node}' depends on both trigger path '${runPath}' and data path '${dataPath}' from the same entity. This can cause unexpected reactivity.`,
238+
),
239+
{ node, triggerPath: runPath, dataPath },
240+
);
241+
}
237242
}
238243
}
239244
}
@@ -256,7 +261,15 @@ export class DependencyMapUtils {
256261

257262
if (!entityConfig) return;
258263

259-
if (!isActionConfig(entityConfig) && !isJSActionConfig(entityConfig)) {
264+
if (isWidget(entityConfig)) {
265+
return;
266+
}
267+
268+
// to not calculate transitive dependencies for JSObject.body and JSObject
269+
if (
270+
isJSActionConfig(entityConfig) &&
271+
(current.includes(".body") || !current.includes("."))
272+
) {
260273
return;
261274
}
262275

0 commit comments

Comments
 (0)