Simplify your stack and build anything. Or everything.
Build tomorrow’s web with a modern solution you truly own.
Code-based nature means you can build on top of it to power anything.
It’s time to take back your content infrastructure.

payload.update help with arrays and hasMany relationship fields

default discord avatar
jakehopking2 years ago
3

What is the recommended approach for updating array and hasMany relationship fields?



### 1) hasMany relationship fields


I have an Customer collection, and I want to add an order id to the hasMany relationship field. What's the approach to take here?



### 2) array fields


If I want to push a new object to an array, what is the recommended approach here?



Some example code for both cases would be

really

helpful here.



Thanks!



@967091941873426493

team - would really appreciate a guide here.



When we create a relationship field, it produces an array at the API level, but when I add a new

id

to the field through

payload.update()

do we again treat is as an array?



Would this be a correct approach:



const payloadCustomer: CustomerType = await payload.findByID({
  collection: 'customers',
  id: newOrUpdatedOrder.customerRelationship.id,
});

if (payloadCustomer.stripe.customerId === '') {
  const stripeCustomer = await stripe.customers.create({
    email: customer.email,
    name: customer.name,
    address: customer.address,
  });

  const updatedCustomer: CustomerType = await payload.update({
    collection: 'customers',
    id: payloadCustomer.id,
    data: {
      stripeCustomerId: stripeCustomer.id,
      orders: [
        ...payloadCustomer.orders,
        newOrUpdatedOrder.id,
      ],
    },
  });
}


and if the

hasMany

is set to false, how do we treat this field from

payload.update

is it an array of length 1, or is it a string of id?



I've found the docs have been updated since the last time I checked many moons ago 👍

  • discord user avatar
    jarrod_not_jared
    2 years ago

    Hey

    @357456032454410240

    to update an array (relationship or not), you need merge the existing array data with the new one as you are doing above.

  • default discord avatar
    jakehopking2 years ago

    Of fundamental importance for anyone who gets stuck on this for more time than they should:



    You need to map over the array you intend to spread back in, and only return the

    id

    .



    A relationship

    hasMany

    only stores an array of id, and when we query with say,

    payload.findById

    it returns these populated as would be expected, so when you spread back in, then you need to filter out everything except the id. Like so:



    orders: [
      ...payloadCustomer.orders.map((order) => order.id),
      newOrUpdatedOrder.id,
    ],


    @281120856527077378

    Thanks, but I'm still a bit confused. The above realisation got me most of the way.... however I notice that the

    hasMany

    can actually hold arrays with multiple items with the same id. Is this expected? How best to filter out?



    do I need to do something like this to ensure no duplicates??



    orders: Array.from(
      new Set([
        ...payloadCustomer.orders.map((order) => order.id),
        newOrUpdatedOrder.id,
      ]),
    ),


    -


    seems like this should be handled at the api level?


    -





    For completeness for others learning this, if the hasMany relationship is new and therefore empty you need to cater for that like so:



    orders: Array.from(
      new Set([
        ...(payloadCustomer?.orders?.length > 0
          ? payloadCustomer.orders.map((order) => order.id)
          : []),
        newOrUpdatedOrder.id,
      ]),
    ),


    Otherwise you'll get undefined errors on the map and everything explodes 💥

  • default discord avatar
    hrxth9 months ago

    mannn you have no idea how long i was stuck on this problem! thank you for that detailed explanation!

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get dedicated engineering support directly from the Payload team.