0

I followed this answer to create a custom attribute on customer with graphQL. The query works great, but if I try to change the value with a mutation, it just returns null. Can anyone please help me with adding this functionality please? Code and example below:

schema.graphql:

type Customer {
  sample_attribute: String @doc(description: "Customer Custom Attribute Show")
    @resolver(
      class: "\\Wrightway\\CustomGraphQl\\Model\\Resolver\\GetCustomerCustomAttr"
    )
}

input CustomerInput {
  sample_attribute: String @doc(description: "Customer Custom Attribute Val")
}

Model/Resolver/GetCustomerCustomAttr.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
declare (strict_types = 1);

namespace Wrightway\CustomGraphQl\Model\Resolver;

use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Config\Element\Field;
use Magento\Framework\GraphQl\Query\ResolverInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;

/**
 * Customer custom attribute field resolver
 */
class GetCustomerCustomAttr implements ResolverInterface
{
    /**
     * @var Magento\Customer\Api\CustomerRepositoryInterface
     */
    protected $customerRepositoryInterface;

    /**
     * @param Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface
     */
    public function __construct(
        \Magento\Customer\Api\CustomerRepositoryInterface $customerRepositoryInterface
    ) {
        $this->customerRepositoryInterface = $customerRepositoryInterface;
    }

    /**
     * @inheritdoc
     */
    public function resolve(
        Field $field,
        $context,
        ResolveInfo $info,
        array $value = null,
        array $args = null
    ) {
        if (!isset($value['model'])) {
            throw new LocalizedException(__('"model" value should be specified'));
        }
        /** @var CustomerInterface $customer */
        $customer = $value['model'];
        $customerId = (int) $customer->getId();
        $customerData = $this->customerRepositoryInterface->getById($customerId);

        /* Get customer custom attribute value */
        if ($customer->getCustomAttribute('sample_attributess')) {
            $customerAttributeVal = $customer->getCustomAttribute('sample_attributess')->getValue();
        } else {
            $customerAttributeVal = null;
        }

        return $customerAttributeVal;
    }
}

Query example (works great):

{
  customer {
    firstname
    sample_attribute
  }
}

returns:

{
  "data": {
    "customer": {
      "firstname": "Adam",
      "sample_attribute": null
    }
  }
}

Mutation example (doesn't work, returns null when attempted to change data):

mutation {
  updateCustomer(
    input: {
      firstname: "Adam",
      sample_attribute: "This is sample text"
    }
  ) {
    customer {
      firstname
      sample_attribute
    }
  }
}

returns (The added data, "This is sample text" returns null, and also returns null on the query.:

{
  "data": {
    "updateCustomer": {
      "customer": {
        "firstname": "Adam",
        "sample_attribute": null
      }
    }
  }
}

What do I need to add to make this work? Help much appreciated.

1 Answer 1

0

I have written an example that interacts with 2 extension attributes. One is called preferred_colour and it does the same thing as your sample_attribute extension attribute

My graphql is like below:

type Customer {    
    preferred_colour: String
        @doc(description: "Customer Preferred Colour")
        @resolver(class: "\\Mbs\\CustomerAttribute\\Model\\Resolver\\GetCustomerPreferredColour")
}

input CustomerInput {
    preferred_colour: String
}

You need a customer repository plugin like below

<type name="Magento\Customer\Api\CustomerRepositoryInterface">
        <plugin name="save_additional_customer_info" type="Mbs\CustomerAttribute\Plugin\AssignAdditionalData" />
    </type>

I add below the plugin code

class AssignAdditionalData
{
    private \Mbs\CustomerAttribute\Model\AdditionalCustomerInfoHandler $additionalCustomerInfoHandler;

    /**
     * @param AdditionalCustomerInfoHandler $additionalCustomerInfoHandler
     */
    public function __construct(
        \Mbs\CustomerAttribute\Model\AdditionalCustomerInfoHandler $additionalCustomerInfoHandler
    ) {
        $this->additionalCustomerInfoHandler = $additionalCustomerInfoHandler;
    }

    public function afterGet(
        \Magento\Customer\Api\CustomerRepositoryInterface $subject,
        \Magento\Customer\Api\Data\CustomerInterface $customer
    ) {
        $this->addAdditionalInfoExtensionAttribute($customer);
        return $customer;
    }

    public function afterGetList(
        \Magento\Customer\Api\CustomerRepositoryInterface $subject,
        \Magento\Customer\Api\Data\CustomerSearchResultsInterface $results
    ) {
        array_map([$this, 'addAdditionalInfoExtensionAttribute'], $results->getItems());
        return $results;
    }

    ..
}

As you can see the plugin hydrates the customer data from the extension attributes data

I add the url to a public repository so that you can see the full code.

customer attribute repository. Particularly, within this code, the class \Mbs\CustomerAttribute\Model\AdditionalCustomerInfoHandler is what you may want to take a look at.

2
  • Thank you, this is a huge help! Commented Aug 26, 2022 at 13:41
  • my pleasure, feel free to thumb up it, it will give me 10 more points :-) Commented Aug 26, 2022 at 14:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.