Skip to content

Bug: Infinite submit in the admin panel when saving a document if the hook uses an update of another document. #13249

@AgrrFoss

Description

@AgrrFoss

Describe the Bug

I ran into this problem a long time ago, and I thought it was my mistake. I used too match hooks in my collection. But I reproduced it on a simple project and realized that it does not depend on me. My example project in repo:
https://github.com/AgrrFoss/test_two_collection.git
I have created a collection of services:

export const Services: CollectionConfig = {
  slug: 'services',
  labels: {
    singular: 'Service',
    plural: 'Services',
  },
  fields: [
    {
      label: 'Place',
      name: 'isPlace',
      type: 'checkbox',
      defaultValue: false
    },
    {
      name: 'title',
      label: 'Name',
      type: 'text',
      required: true,
      minLength: 2,
      maxLength: 50,
    },
{
  type: 'collapsible',
  admin: {
    position: 'sidebar',
  },
  fields: [
    {
      name: 'moderationStatus',
      label: 'Статус страницы',
      type: 'select',
      options: [
        { label: 'Draft', value: 'draft' },
        { label: 'Awaiting moderation', value: 'on_moderation' },
        { label: 'Moderation failed', value: 'failed_moderation' },
        { label: 'Published', value: 'published' },
        { label: 'inactive', value: 'inactive' },
      ],
      admin: {
        position: 'sidebar',
      },
      defaultValue: () => 'draft',
    },
    {
      name: 'moderationMessage',
      type: 'textarea',
      admin: {
        condition: (siblingData) => {
          return siblingData.moderationStatus === 'failed_moderation'
        },
        disableListColumn: true,
      },
    },
  ],
},
{
  name: 'subscriptions',
  label: 'Actice subscription',
  admin: {
    position: 'sidebar',
    // readOnly: true,
  },
  type: 'select',
  options: subscriptionTypes,
  hasMany: true,
},
{
  name: 'rating',
  label: 'Рейтинг',
  type: 'number',
  admin: {
    readOnly: true,
    position: 'sidebar',
  },
}
  ]
}

and collection ServicesSubscriptions:

export const ServicesSubscriptions: CollectionConfig = {
  slug: 'servicesSub',
  hooks: {
    beforeRead: [checkServicesSubscriptionStatus],
    afterChange: [updateServicesSubscriptionListAfterChange],
    afterDelete: [updateServicesSubscriptionListAfterDelete]
  },
  fields: [
    {
      name: 'type',
      label: 'Тип',
      type: 'select',
      options: [
  {label: 'pro', value: 'pro'},
  {label: 'Priority placement', value: 'priority'},
  {label: 'Static banners', value: 'banners'}
],
      required: true,
    },
    {
      name: 'refer',
      label: 'refer to',
      type: 'relationship',
      relationTo: 'services',
      required: true,
    },
    {
      name: 'endDate',
      type: 'date',
      admin: {
        date: {
          displayFormat: 'd MMM yyy',
        },
      },
    },
{
  name: 'subscriptionStatus',
  type: 'select',
  options: [
    {label: 'active', value: 'active'},
    {label: 'expect_payment', value: 'expect_payment'},
    {label: 'expired', value: 'expired'},
  ],
}

I used hook updateServicesSubscriptionListAfterChange so that when an active subscription related to a service is created, a line with the subscription type is added to the subscriptions field of the service document. But when I click "save", the message "submit" and infinity loader appears in the admin panel.
I now about context in hook
and i used it:

export const checkServicesSubscriptionStatus: CollectionBeforeReadHook = async ({context, doc, req}) => {
  if(context.triggerAfterRead || context.localApiOperation){
    return
  }
...
}
// updateServicesSubscriptionList.ts

  if (newSubscriptionArray) {
    const result = await payload.update({
      collection: 'services',
      id: currentSubscriptionReferId,
      data: {
        subscriptions: newSubscriptionArray,
      },
      depth: 0,
      draft: false,
      context: {
        localApiOperation: true
      }
    })
    console.log('result: ', result)
  }

I've seen this bug before. When a service review was added to the collection of reviews, I wanted to recalculate the rating and update the rating field for the corresponding service.
I've spent dozens of hours thinking I've missed something and looking for a bug. Then I gave up and made this feature through the beforeRead in collection services hook. But this is not the best solution.

Link to the code that reproduces this issue

https://github.com/AgrrFoss/test_two_collection.git

Reproduction Steps

clone repo
~yarn install --frozen-lock
add .env
go to admin panel
create first service
create subscription with status active
click save
Look at the endless loader

Which area(s) are affected? (Select all that apply)

db-postgres

Environment Info

DATABASE_URI=postgres://pguser:pgPass@127.0.0.1:5432/test-two-collection
PAYLOAD_SECRET=58ed4098a4ec21c642e0c759
# Added by Payload

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions