Answers.Body: <p>I don't think you want to use the <code>Fields::EVENT_BEFORE_PARSE_FIELD</code> event here - that's too late in the process to do what you need. Instead you should fix the property in your input data that you want to map to categories, by preprocessing it into an array. The easiest way to do this in Feed Me is with a <a href="https://docs.craftcms.com/feed-me/v4/developers/data-types.html" rel="nofollow noreferrer">custom Data Type</a>.</p>
  <p>All we need to do in this case is extend Feed Me's built-in JSON Data Type and loop over the items in the feed to post process them:</p>
  <pre class="lang-php prettyprint-override"><code>&lt;?php
  
  namespace modules\datatypes;
  
  use craft\feedme\datatypes\Json;
  use illuminate\Support\Collection;
  
  class CustomJsonDatatype extends Json
  {
      /**
       * @var string
       */
      // This will be the name of the Feed Type visible when setting up the feed
      public static string $name = 'Custom JSON';
      
      // Public Methods
      // =========================================================================
  
      /**
       * @inheritDoc
       */
      public function getFeed($url, $settings, bool $usePrimaryElement = true): array
      {
          // Get the feed from the parent class
          $feed = parent::getFeed($url, $settings, $usePrimaryElement);
  
          // Map over the data key with our custom transformer method
          $feed['data'] = collect($feed['data'])
              -&gt;map(function($item) {
                  return $this-&gt;transformItem(collect($item));
              })
              -&gt;toArray();
          return $feed;
      }
      
      public function transformItem(Collection $item): ?Collection
      {
          // do whatever you want here to each item - the below is untested but _should_ work
          if ($item-&gt;Category) {
              $values = collect(explode('|', $item-&gt;Category));
              $item-&gt;put('Category', $values-&gt;map(fn($value) =&gt; trim($value))-&gt;toArray());
          }
          
          return $item;
      }
  }
  </code></pre>
  <p>Then in a custom module register your Data Type with Feed Me:</p>
  <pre class="lang-php prettyprint-override"><code>&lt;?php
  
  namespace modules;
  
  use Craft;
  use craft\feedme\events\RegisterFeedMeDataTypesEvent;
  use craft\feedme\services\DataTypes;
  use modules\datatypes\CustomJsonDatatype;
  use yii\base\Event;
  use yii\base\Module as BaseModule;
  
  class Module extends BaseModule
  {
      public function init(): void
      {
          Craft::setAlias('@modules', __DIR__);
  
          parent::init();
  
          Craft::$app-&gt;onInit(function() {
              $this-&gt;registerFeedMeDataTypes();
          });
      }
      
      private function registerFeedMeDataTypes(): void
      {
          // see https://docs.craftcms.com/feed-me/v4/developers/data-types.html#the-registerfeedmedatatypes-event
          Event::on(
              DataTypes::class,
              DataTypes::EVENT_REGISTER_FEED_ME_DATA_TYPES,
              static function(RegisterFeedMeDataTypesEvent $e) {
                  $e-&gt;dataTypes[] = CustomJsonDatatype::class;
              }
          );
      }
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-08-02T13:06:14.193Z
Answers.Text: Thank you @Tom Davies, this seems like a very good answer from a very wise man.
Answers.UserDisplayName: John
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-09-14T13:42:54.077Z
Answers.Text: You forgot "handsome"
Answers.UserDisplayName: Tom Davies
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-08-02T11:11:45.357Z
Answers.LastActivityDate: 2023-08-02T11:11:45.357Z
Answers.UserDisplayName: Tom Davies
Body: <p>I've got a json data feed that has related entry titles in a pipe delimited format like so:</p>
  <p><code>'Entry1 | Entry2 | Entry3'</code></p>
  <p>I thought feedme actually used to be ok with that, but it looks like now it has to be an array.</p>
  <p>So i'm trying to hook into a FeedMe event and transform that data into an array before FeedMe then parses it.</p>
  <pre><code>Event::on(Fields::class, Fields::EVENT_BEFORE_PARSE_FIELD, function(FieldEvent $event) {
              $value = $event-&gt;parsedValue;
              if ($event-&gt;feed['id'] == 1) {
                  if ($event-&gt;fieldHandle === 'category') {
                      $newValue = array_map('trim', explode('|', $value));
                      $event-&gt;parsedValue = $newValue;
                  }
              }
          });
  </code></pre>
  <p>This doesn't seem to be having any effect though, what am I missing?</p>
  <p>Thx!</p>
  
Tags: <plugin-feedme>
Title: In FeedMe transform one data element before it gets parsed
ThreadText: # In FeedMe transform one data element before it gets parsed
  
  (Asked by: username_0 on 2023-08-01)
  
  I've got a json data feed that has related entry titles in a pipe delimited format like so:
  
  `'Entry1 | Entry2 | Entry3'`
  
  I thought feedme actually used to be ok with that, but it looks like now it has to be an array.
  
  So i'm trying to hook into a FeedMe event and transform that data into an array before FeedMe then parses it.
  
  ```
  Event::on(Fields::class, Fields::EVENT_BEFORE_PARSE_FIELD, function(FieldEvent $event) {
              $value = $event->parsedValue;
              if ($event->feed['id'] == 1) {
                  if ($event->fieldHandle === 'category') {
                      $newValue = array_map('trim', explode('|', $value));
                      $event->parsedValue = $newValue;
                  }
              }
          });
  
  ```
  
  This doesn't seem to be having any effect though, what am I missing?
  
  Thx!
  
  **Tags:** plugin-feedme
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2023-08-02. Score: 3 | Accepted answer
  
  I don't think you want to use the `Fields::EVENT_BEFORE_PARSE_FIELD` event here - that's too late in the process to do what you need. Instead you should fix the property in your input data that you want to map to categories, by preprocessing it into an array. The easiest way to do this in Feed Me is with a [custom Data Type](https://docs.craftcms.com/feed-me/v4/developers/data-types.html).
  
  All we need to do in this case is extend Feed Me's built-in JSON Data Type and loop over the items in the feed to post process them:
  
  ```php
  <?php
  
  namespace modules\datatypes;
  
  use craft\feedme\datatypes\Json;
  use illuminate\Support\Collection;
  
  class CustomJsonDatatype extends Json
  {
      /**
       * @var string
       */
      // This will be the name of the Feed Type visible when setting up the feed
      public static string $name = 'Custom JSON';
      
      // Public Methods
      // =========================================================================
  
      /**
       * @inheritDoc
       */
      public function getFeed($url, $settings, bool $usePrimaryElement = true): array
      {
          // Get the feed from the parent class
          $feed = parent::getFeed($url, $settings, $usePrimaryElement);
  
          // Map over the data key with our custom transformer method
          $feed['data'] = collect($feed['data'])
              ->map(function($item) {
                  return $this->transformItem(collect($item));
              })
              ->toArray();
          return $feed;
      }
      
      public function transformItem(Collection $item): ?Collection
      {
          // do whatever you want here to each item - the below is untested but _should_ work
          if ($item->Category) {
              $values = collect(explode('|', $item->Category));
              $item->put('Category', $values->map(fn($value) => trim($value))->toArray());
          }
          
          return $item;
      }
  }
  
  ```
  
  Then in a custom module register your Data Type with Feed Me:
  
  ```php
  <?php
  
  namespace modules;
  
  use Craft;
  use craft\feedme\events\RegisterFeedMeDataTypesEvent;
  use craft\feedme\services\DataTypes;
  use modules\datatypes\CustomJsonDatatype;
  use yii\base\Event;
  use yii\base\Module as BaseModule;
  
  class Module extends BaseModule
  {
      public function init(): void
      {
          Craft::setAlias('@modules', __DIR__);
  
          parent::init();
  
          Craft::$app->onInit(function() {
              $this->registerFeedMeDataTypes();
          });
      }
      
      private function registerFeedMeDataTypes(): void
      {
          // see https://docs.craftcms.com/feed-me/v4/developers/data-types.html#the-registerfeedmedatatypes-event
          Event::on(
              DataTypes::class,
              DataTypes::EVENT_REGISTER_FEED_ME_DATA_TYPES,
              static function(RegisterFeedMeDataTypesEvent $e) {
                  $e->dataTypes[] = CustomJsonDatatype::class;
              }
          );
      }
  }
  
  ```
  
  > **Comments:**
  > **username_0**: Thank you @username_1, this seems like a very good answer from a very wise man.  
  > **username_1**: You forgot "handsome"  
  
  ---
  
  