Updating specific object attribute in type array

default discord avatar
Samy
last month
8

Here is my data structure :


  {
      name: "userPlannerTasks",
      type: "group",
      fields: [
        {
          name: "daily",
          label: "Every day",
          type: "array",
          fields: [
            {
              name: "title",
              label: "Title",
              type: "text",
              required: true,
            },
            {
              name: "frequency",
              label: "Frequency",
              type: "text",
              required: true,
            },
            {
              name: "index",
              label: "Index",
              type: "number",
              required: true,
            },
            {
              name: "startingTime",
              label: "Starting time",
              type: "text",
              required: false,
            },
            {
              name: "endingTime",
              label: "Ending time",
              type: "text",
              required: false,
            },
            {
              name: "completedAt",
              label: "Completion time",
              type: "date",
              required: false,
            },
          ],
        {
          name: "weekly",
          label: "Every week",
          type: "array",
          fields: [same as daily]
},


My use case goes like this :


- I have a front-end that display daily tasks.


- A user can have many daily tasks.


- When a user completes a task, he can check it to mark it completed.



My goal is to update in the array of daily tasks the right object according to the index of the daily task shown in the front-end (FE). E.G : If my task checked in the FE is the second one in the list, I want to update the document at index 1.



From what I understand I could simply send the whole array of daily tasks with a patch request through

/my_slug/documentId

.



Although I don't know if it's possible to target an object in a array through Payload's REST API or I have to use the hooks?



Thank you 🙂

  • discord user avatar
    dribbens
    Payload Team
    last month

    You see an id has been added to each object in the array. If you send only the object you want to modify with the id in the patch it will update just that one. None of the other objects in the array should be affected.

  • default discord avatar
    Samy
    last month

    Following my structure of the object I managed to achieve what I wanted to do through a "PATCH" request. Much appreciated for your help @dribbens

    :niceone:

    !



    Mhmm... for some reason it doesn't seem to work. Here's my current document :



    {
      "_id": {
        "$oid": "64dae4b246f3b71b7c8b8af2"
      },
      "user": "a_user_id",
      "userPlannerTasks": {
        "daily": [
          {
            "title": "Make your bed",
            "frequency": "daily",
            "index": 0,
            "id": "74b70c73-c31c-485f-b12c-bd84a4cf5cbb"
          },
          {
            "title": "Make your bed",
            "frequency": "daily",
            "index": 1,
            "id": "ce3a56d4-e714-4e80-a6bc-5b408061aeb7"
          }
        ],
        "weekly": [],
        "monthly": [],
        "yearly": []
      },
      "updatedAt": {
        "$date": "2023-08-16T04:43:21.902Z"
      }
    }

    And here is my payload :



    {
        "userPlannerTasks":
        {
            "daily":[
                {
                    "id": "74b70c73-c31c-485f-b12c-bd84a4cf5cbb",
                    "completedAt": "2024-08-15T04:22:05.913Z"
                }
            ]
        }
    }


    Here is my query :

    {{api-link}}/user_planner_tasks/64dae4b246f3b71b7c8b8af2

    . It's a

    PATCH

    request



    According to your input, it should only update the first task of making your bed. It seems to patch the current document with the current payload therefore erasing the second instance of

    Making your bed

    NB :

    The id for each task is generated through the front-end application with uuidv4(). I don't know if it has an impact.

  • discord user avatar
    dribbens
    Payload Team
    last month

    Oh my bad. If you can pass through the rest of the task IDs they won't get removed. Are you dealing with a large number of items in the array? What is the reason you don't want to do that?



    You could add a custom endpoint that gets the document and only updates the one item in the array matching the id found instead of changing them all.



    Another alternative would be to add a hidden group field with the same subfields as your array. Using a before change hook you are going to find and set the item in your array by the uuid, leaving all the others the same and not returning your virtual group value so that it isn't persisted.

  • default discord avatar
    Samy
    last month

    Thanks @dribbens for your answer



    Yep exactly I could end up having hundred of items being sent because of one simple modification. Lets say I have 100 daily tasks and I want to complete the second task only. I would need to send the data of the 99 other tasks also.



    My initial take was to go with custom end points but while playing with them I figured out that the access control don't apply to custom endpoints?



    Also I'm not really understanding what do you mean by adding a hidden group field?

  • discord user avatar
    dribbens
    Payload Team
    last month

    A custom endpoint is probably easier than the hidden group idea for updating an item in the array.



    You can use access control all the same by passing the

    req

    through to payload.update(). It will provide the same validation and access control as if you were hitting the endpoint directly.

  • default discord avatar
    superwafflepuffs
    last month

    Just curious...wouldn't it be easier to just create a separate collection for your tasks and map them as a relationship to a task list?

  • default discord avatar
    Samy
    last month

    @dribbens Yep I ended up doing a custom endpoint. I really wanted to stick with Payload's REST API.



    @superwafflepuffs My initial approach was to map them as a relationship but I can't remember why it didn't work. Now that I think of it, doing so would allow me to update a single task as intended...

  • default discord avatar
    superwafflepuffs
    last month

    Ye, also just thinking of other good reasons for a TaskCollection { listId } type setup would be if you wanted to move tasks between lists that would be really easy. cloning tasks as well.

Open the post
Continue the discussion in Discord
Like what we're doing?
Star us on GitHub!

Star

Connect with the Payload Community on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.