diff --git a/src/fields/hooks/beforeChange/promise.ts b/src/fields/hooks/beforeChange/promise.ts index ea97983c96..e37e2ea516 100644 --- a/src/fields/hooks/beforeChange/promise.ts +++ b/src/fields/hooks/beforeChange/promise.ts @@ -50,7 +50,10 @@ export const promise = async ({ skipValidation, }: Args): Promise => { const passesCondition = (field.admin?.condition) ? field.admin.condition(data, siblingData) : true; - const skipValidationFromHere = skipValidation || !passesCondition; + let skipValidationFromHere = skipValidation || !passesCondition; + + const defaultLocale = req.payload.config?.localization ? req.payload.config.localization?.defaultLocale : 'en'; + const operationLocale = req.locale || defaultLocale; if (fieldAffectsData(field)) { if (typeof siblingData[field.name] === 'undefined') { @@ -73,6 +76,17 @@ export const promise = async ({ } } + if (siblingData[field.name] === null) { + if (field.localized && ['array', 'blocks'].includes(field.type)) { + if (operationLocale !== defaultLocale) { + // localized fields set to null and not the default locale, should be set to undefined + // this way fallback locale can be used + siblingData[field.name] = undefined; + skipValidationFromHere = true; + } + } + } + // Execute hooks if (field.hooks?.beforeChange) { await field.hooks.beforeChange.reduce(async (priorHook, currentHook) => { @@ -95,13 +109,11 @@ export const promise = async ({ // Validate if (!skipValidationFromHere && field.validate) { - let valueToValidate; + let valueToValidate = siblingData[field.name]; if (['array', 'blocks'].includes(field.type)) { const rows = siblingData[field.name]; valueToValidate = Array.isArray(rows) ? rows.length : 0; - } else { - valueToValidate = siblingData[field.name]; } const validationResult = await field.validate(valueToValidate, { @@ -127,21 +139,20 @@ export const promise = async ({ if (field.localized) { mergeLocaleActions.push(() => { if (req.payload.config.localization) { - const localeData = req.payload.config.localization.locales.reduce((locales, localeID) => { - let valueToSet = siblingData[field.name]; + const localeData = req.payload.config.localization.locales.reduce((localizedValues, locale) => { + const fieldValue = locale === req.locale + ? siblingData[field.name] + : siblingDocWithLocales?.[field.name]?.[locale]; - if (localeID !== req.locale) { - valueToSet = siblingDocWithLocales?.[field.name]?.[localeID]; - } - - if (typeof valueToSet !== 'undefined') { + // update locale value if it's not undefined + if (typeof fieldValue !== 'undefined') { return { - ...locales, - [localeID]: valueToSet, + ...localizedValues, + [locale]: fieldValue, }; } - return locales; + return localizedValues; }, {}); // If there are locales with data, set the data @@ -221,7 +232,6 @@ export const promise = async ({ await Promise.all(promises); } - break; } @@ -256,7 +266,6 @@ export const promise = async ({ await Promise.all(promises); } - break; } diff --git a/src/mongoose/buildSchema.ts b/src/mongoose/buildSchema.ts index c434a6dc15..e4afffb751 100644 --- a/src/mongoose/buildSchema.ts +++ b/src/mongoose/buildSchema.ts @@ -330,6 +330,7 @@ const fieldToSchemaMap: Record = { array: (field: ArrayField, schema: Schema, config: SanitizedConfig, buildSchemaOptions: BuildSchemaOptions) => { const baseSchema = { ...formatBaseSchema(field, buildSchemaOptions), + default: undefined, type: [buildSchema( config, field.fields, @@ -392,7 +393,10 @@ const fieldToSchemaMap: Record = { }); }, blocks: (field: BlockField, schema: Schema, config: SanitizedConfig, buildSchemaOptions: BuildSchemaOptions): void => { - const fieldSchema = [new Schema({}, { _id: false, discriminatorKey: 'blockType' })]; + const fieldSchema = { + default: undefined, + type: [new Schema({}, { _id: false, discriminatorKey: 'blockType' })], + }; schema.add({ [field.name]: localizeSchema(field, fieldSchema, config.localization), diff --git a/test/fields/config.ts b/test/fields/config.ts index 4dbdd6e82f..dae155e758 100644 --- a/test/fields/config.ts +++ b/test/fields/config.ts @@ -57,6 +57,7 @@ export default buildConfig({ localization: { defaultLocale: 'en', locales: ['en', 'es'], + fallback: true, }, onInit: async (payload) => { await payload.create({ diff --git a/test/fields/int.spec.ts b/test/fields/int.spec.ts index 09d4a90211..7f6c3d8408 100644 --- a/test/fields/int.spec.ts +++ b/test/fields/int.spec.ts @@ -276,13 +276,13 @@ describe('Fields', () => { }); }); - it('should return empty array for arrays when no data present', async () => { + it('should return undefined arrays when no data present', async () => { const document = await payload.create({ collection: arrayFieldsSlug, data: arrayDoc, }); - expect(document.potentiallyEmptyArray).toEqual([]); + expect(document.potentiallyEmptyArray).toBeUndefined(); }); it('should create with ids and nested ids', async () => {