8

I have a multi-valued taxonomy reference field named field_classrooms in a node type. I use below code to delete the value in the field.

$node = Drupal\node\Entity\Node::load('1512');
unset($node->field_classrooms[0]);
$node->save();

I can't figure out what I am doing wrong here.

8 Answers 8

12

Maybe something like this could help you out

// Get the list of the associated classrooms ...
$classrooms = $node->get('field_classrooms')->getValue();
// ... if there are any associated classrooms ...
if(!empty($classrooms)) {
  foreach($classrooms as $classroom) {
    // ... get the key of the classroom
    $key = array_search(current($classroom), array_column($classrooms, key($classroom)));
    // ... remove the relationship ...
    $node->get('field_classrooms')->removeItem($key);
  }
  // ... and save the node.
  $node->save();
}

If you want to remove a single classroom from the list and you already know the tid

private function removeClassroomFromNode($node, $tid) {
  if(null != $node) {
    // ... get the list of associated classrooms
    $classrooms = $node->get('field_classrooms')->getValue();
    // ... get the key of the classroom
    $key = array_search($tid, array_column($classrooms, 'target_id'));
    // ... remove the classroom
    $node->get('field_classrooms')->removeItem($key);
    // ... save the node.
    $node->save();
  }
}
3
  • 1
    Thanks for the response. I tried removeItem instead of unset but still it doesn't seem to remove the value. It is a multi value field btw. May 23, 2018 at 9:21
  • 1
    The removeItem() method uses unset() api.drupal.org/api/drupal/…
    – Rockabelly
    May 23, 2018 at 11:18
  • So unnecessarily complex ... Drupal is something else...
    – AlxVallejo
    Aug 17 at 21:22
4

You can use below code for removing items in the reference field in Drupal 8 :

/** @var \Drupal\Core\Entity\ContentEntityBase $entity */
$entity = \Drupal::entityTypeManager()->getStorage('node')->load($nid);

$tids = $entity->get('field_classrooms')->getValue();

$updatedTerms = [];
foreach($tids as $term) {
  if ($term['target_id'] != 35)
    $updatedTerms[] = ['target_id' => $term['target_id']];      
}

$entity->field_notifications = $updatedTerms;

$entity->save();
3

You can simply set to empty

$node->set('field_classrooms', []);
2

You can remove the first item of a list just calling

$node->get('field_classrooms')->removeItem(0);
1
  • Ya but you're shooting in the dark - how do you know which index to delete?
    – AlxVallejo
    Aug 17 at 21:38
2

You can remove a particular referenced entity by id with this code:

    $entity->get('my_field')->setValue(array_filter($entity->get('my_field')->getValue(), function ($value) use ($id) {
      return ($value['target_id'] != $id);
    }));
2

Another way of bulk or selective delete is elegant filter() method.

Example:

use Drupal\Core\TypedData\TypedDataInterface;

$nodeStorage = \Drupal::service('entity_type.manager')->getStorage('node');
/**
 * @var \Drupal\node\Entity\Node $node
 */
$node = $nodeStorage->load($nid);
$classrooms = $node->get('field_classrooms');
$classrooms->filter(function (TypedDataInterface $item) {
  // You can do some operations on field item like: $item->getValue();
  // Returning TRUE in an iteration will remove the item.
  return TRUE;
});
$node->save();
1
  • Thanks! This was the winner for me because the filter() function lets you remove more than one entity reference in one go. If you try to do this with a loop you always end up with array indexing errors.
    – ocean
    Feb 13 at 3:20
1

Meanwhile you can take help from this code -

$node = \Drupal\node\Entity\Node::load('1512');
// Removes '0' index element.
$node->set('field_classrooms', array_slice($node->get('field_classrooms')->getValue(), 1));
$node->save();
0

the item is removed based on the index number of the list, so you need to figure out the index you want to remove,

1.- get all the referenced items

$array_of_referenced_items = $node->get('field_SOMETHING_ref')->getValue();

2.- search on the array for the index of the item you are trying to remove.

$index_to_remove = array_search(['target_id' => ID_TO_SEARCH], $array_of_referenced_items);

3.- Remove the reference by the index.

$node->get('field_SOMETHING_ref')->removeItem($index_to_remove);

Your Answer

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

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