Skip to content

Incorrect merging of base resources in recursivelyMergeBaseResources function #23620

@SimonXcx

Description

@SimonXcx

Is there an existing issue for this?

  • I have searched the existing issues

Description

The recursivelyMergeBaseResources function in npm/ng-packs/packages/core/src/lib/services/localization.service.ts has a bug in its reduce implementation that causes some base resource texts to be lost during the merging process.

Reproduction Steps

The Bug
The issue is in the reduce function where item.texts is used in every iteration instead of the accumulated result. This means:
Each iteration starts fresh with the original item.texts
Previous iterations' merged results are overwritten
Only the last base resource's texts are preserved along with the original item.texts
Example
Input:
resources = { a: { baseResources: ["b", "c", "d"], texts: { dup: "a", specialA: "a" } }, b: { baseResources: [], texts: { dup: "b", specialb: "b" } }, c: { baseResources: [], texts: { dup: "c", specialc: "c" } }, d: { baseResources: [], texts: { dup: "d", speciald: "d" } }

Expected behavior

Expected Output:
{ "a": { "baseResources": ["b", "c", "d"], "texts": { "dup": "a", "specialA": "a", "specialb": "b", "specialc": "c", "speciald": "d" } } }

Actual behavior

Actual Output:
{ "a": { "baseResources": ["b", "c", "d"], "texts": { "dup": "a", "specialA": "a", "speciald": "d" // Only the last base resource is preserved } } }

Regression?

No response

Known Workarounds

No response

Version

9.2.3

User Interface

Common (Default)

Database Provider

EF Core (Default)

Tiered or separate authentication server

None (Default)

Operation System

Windows (Default)

Other information

Root Cause
The problem occurs because each reduce iteration uses { ...baseItem.texts, ...item.texts } instead of {...baseItem.texts, ...acc.texts }. This means the accumulated result from previous iterations (acc.texts) is ignored, and only the current base resource is merged with the original item.texts.
Proposed Fix
change

function recursivelyMergeBaseResources( baseResourceName: string, source: ResourceDto, ): ApplicationLocalizationResourceDto { const item = source[baseResourceName]; if (item.baseResources.length === 0) { return item; } return item.baseResources.reduce((acc, baseResource) => { const baseItem = recursivelyMergeBaseResources(baseResource, source); const texts = { ...baseItem.texts, ...item.texts }; return { ...acc, texts }; }, item); }

to

function recursivelyMergeBaseResources( baseResourceName: string, source: ResourceDto, ): ApplicationLocalizationResourceDto { const item = source[baseResourceName]; if (item.baseResources.length === 0) { return item; } return item.baseResources.reduce((acc, baseResource) => { const baseItem = recursivelyMergeBaseResources(baseResource, source); const texts = { ...baseItem.texts,...acc.texts }; return { ...acc, texts }; }, item); }

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions