GraphQL update mutation

I have created discount function for shipping using discountAutomaticAppCreate mutation. it is working well and good. the details are fetched from the frontend and passed for applying discount logic in the storefront.

now I want to update the function using update mutation. can someone who is familiar with this help me out??.

Can you please help with what do you want to update about the function?

As I understand, once you create a function, you receive a function ID and that’s pretty much it.

You can create metafields on that function but that doesn’t require discountfunctionAutomaticAppUpdate.

so like I’m passing some additional details through metafields for the backend discount logic to have dynamic behaviour. When trying to update, how should I send the updated details?
I’m sending in this format.

const updateDiscountResponse = await admin.graphql(`
    mutation discountAutomaticAppUpdate($id: ID!, $automaticAppDiscount: DiscountAutomaticAppInput!) {
      discountAutomaticAppUpdate(id: $id, automaticAppDiscount: $automaticAppDiscount) {
        userErrors {
          field
          message
        }
        automaticAppDiscount {
          discountId
          title
          startsAt
          endsAt
        }
      }
    }`, 
    {
      variables: {
        id: discountId,
        automaticAppDiscount: {
          title: `${offerData.offerTitle}-ShippingDiscount`,
          startsAt: offerData.startDate,
          endsAt: offerData.endDate,
          metafields: [
            {
              namespace: "$app:shipping-discount",
              key: "function-configuration",
              type: "json",
              value: JSON.stringify({
                value 1,
                 value 2,
                  value 3
              })
            }
          ]
        }
      }
    });

This looks good. Are you facing any issues with this? Can you please share the error if you are receiving any errors?

I hope this can provide you some information on the issue I’m facing.

Understood.

The issue seems to be that the update mutation doesn’t support upserting a metafield.

What is means?
You can either create a new metafield in the update mutation or update an existing metafield using it’s ID

What should be done?
During the discountAutomaticAppCreate mutation when you’re creating a metafield. Get the ID of the metafield.

During the discountAutomaticAppUpdate mutation, send the ID of the metafield as well in the query.

Alternatively, you can use metafieldsSet mutation to set metafields separately.

Where the ownerId would be discountNode ID.
Ex: gid://shopify/DiscountAutomaticNode/XXX

More about metafieldsSet

In the discountAutomaticAppCreate mutation, there is no metafield Id or other details about it returned. Could you tell me how can I get the metafield details associated to the discount function… So that I can store those details into DB and use it for update purpose.

I’m attaching my create mutation code also. Kindly have a look into it.

`#graphql
          mutation discountAutomaticAppCreate($automaticAppDiscount: DiscountAutomaticAppInput!) {
            discountAutomaticAppCreate(automaticAppDiscount: $automaticAppDiscount) {
              userErrors {
                field
                message
              }
              automaticAppDiscount {
                discountId
                title
                startsAt
                endsAt
                status
                appDiscountType {
                  appKey
                  functionId
                }
              }
            }
          }`,
        {
          variables: {
            automaticAppDiscount: {
              title: `${offerData.offerTitle}-ShippingDiscount`,
              functionId: SHIPPING_DISCOUNT_FUNCTION_ID, 

              startsAt: offerData.startDate,
              endsAt: offerData.endDate,
              metafields: [
                {
                  namespace: "$app:shipping-discount",
                  key: "function-configuration",
                  type: "json",
                  value: JSON.stringify({
                    value 1,
                    value 2,
                    value 3
                  })
                }
              ]
            }
          }
        }

I would suggest, don’t pass metafields in the create or update mutation.

Instead, use the metafieldsSet mutation to add metafields.

Your queries would change accordingly:

Discount Automatic App Create Mutation

`#graphql
          mutation discountAutomaticAppCreate($automaticAppDiscount: DiscountAutomaticAppInput!) {
            discountAutomaticAppCreate(automaticAppDiscount: $automaticAppDiscount) {
              userErrors {
                field
                message
              }
              automaticAppDiscount {
                discountId
                title
                startsAt
                endsAt
                status
                appDiscountType {
                  appKey
                  functionId
                }
              }
            }
          }`,
        {
          variables: {
            automaticAppDiscount: {
              title: `${offerData.offerTitle}-ShippingDiscount`,
              functionId: SHIPPING_DISCOUNT_FUNCTION_ID, 

              startsAt: offerData.startDate,
              endsAt: offerData.endDate
            }
          }
        }

Metafields Set Mutation

`#graphql
mutation MetafieldsSet($metafields: [MetafieldsSetInput!]!) {
  metafieldsSet(metafields: $metafields) {
    metafields {
      id
      key
      namespace
      value
    }
    userErrors {
      field
      message
      code
    }
  }
}
{
  variables: {
    metafields: [{
      ownerId: "`discountId`", // Obtained from Create Mutation
      namespace: "$app:shipping-discount",
      key: "function-configuration",
      type: "json",
      value: JSON.stringify({
        value 1,
        value 2,
        value 3
      })
    }]
  }
}

Let me know if this works.

This is what I was also thinking about ( to create the metafield using MetafieldSet and map with the discount function). For the update mutation, can I just update the metafield alone using the discountID of the discount function. In such case, we do not need update mutation right. I just think of this way. What is your suggestion… Is there any alternate way to update the mutation, when there is a change from the UI. Say, I’m passing three values from the UI in the initial creation process and later I update the values from UI and want the discount function to work with the updated values.

That is correct. You don’t need to use the update mutation to update the metafield.

You only need to call the update mutation if there are any changes in title or timeframe of the discount.

For updating metafield, you can simply use metafieldsSet mutation.

Thanks for the great help. It is actually working well. I implemented the discount function and metafield creation successfully. I’m facing an issue in the data storing into DB; I’m working on it. After that, I’ll let you know once the update mutation is also working fine.

I have another query. This is a remix app. By default when installing an app in the dev store, the details of the store is received. The shopify creates a session schema on its own to handle authentication right. In session schema, the shop field is available which stores the URL of the store. But when I fetched the store details using GraphQL mutation, it has a field named shopId. When I authenticate user in the server-side actions, the session schema should be used. But it doesn’t have a field named shopId right. If then how can we authenticate the store when accessing to the server-side actions?

Not entirely sure about the remix app.

But if you are looking for something unique to authenticate with. Use myshopifyDomain of the store. Those are always unique.

1 Like

Thank you Mr. Prakhar. It was great communicating with you. I’m completely new to this shopify development. I’m learning by doing. Sometimes I get issues and stuck somewhere. It takes a bit of time to solve it. But, this update issue was a prolonged one which I was facing. Your help in this played a crucial role to get me out this and learn how it works. Thank you once again for the continuous help.

Thank you…

1 Like

Hi. I’m facing issue with the discount combinations part. I’m sharing the screenshot for your reference.

I’m sharing my code also. It occurs in the discount create mutation:

mutation discountAutomaticAppCreate($automaticAppDiscount: DiscountAutomaticAppInput!) {
            discountAutomaticAppCreate(automaticAppDiscount: $automaticAppDiscount) {
              userErrors {
                field
                message
              }
              automaticAppDiscount {
                discountId
                title
                startsAt
                endsAt
                status
                appDiscountType {
                  appKey
                  functionId
                }
                combinesWith {
                  orderDiscounts
                  productDiscounts
                  shippingDiscounts
                }
              }
            }
          }`,
        {
          variables: {
            automaticAppDiscount: {
              title: `${offerData.offerTitle}-ShippingDiscount`,
              functionId: SHIPPING_DISCOUNT_FUNCTION_ID, // Your function ID from env
              combinesWith: {
                orderDiscounts: combinationsArray.includes('orderDiscount') ? true : false,
                productDiscounts: combinationsArray.includes('productDiscount') ? true : false,
                shippingDiscounts: true,
              },
              startsAt: offerData.startDate,
              endsAt: offerData.endDate
            }
          }
        }mutation discountAutomaticAppCreate($automaticAppDiscount: DiscountAutomaticAppInput!) {
            discountAutomaticAppCreate(automaticAppDiscount: $automaticAppDiscount) {
              userErrors {
                field
                message
              }
              automaticAppDiscount {
                discountId
                title
                startsAt
                endsAt
                status
                appDiscountType {
                  appKey
                  functionId
                }
                combinesWith {
                  orderDiscounts
                  productDiscounts
                  shippingDiscounts
                }
              }
            }
          }`,
        {
          variables: {
            automaticAppDiscount: {
              title: `${offerData.offerTitle}-ShippingDiscount`,
              functionId: SHIPPING_DISCOUNT_FUNCTION_ID, // Your function ID from env
              combinesWith: {
                orderDiscounts: combinationsArray.includes('orderDiscount') ? true : false,
                productDiscounts: combinationsArray.includes('productDiscount') ? true : false,
                shippingDiscounts: true,
              },
              startsAt: offerData.startDate,
              endsAt: offerData.endDate
            }
          }
        }