Drupal 8/9 : build form state from node entity

Profile picture for user a.berramou
Azz-eddine BERRAMOU 7 September, 2021

I was working on adding preview graphql button to node tabs to simplified previewing node in the frontend without going back to edit page and then click preview.

i'm using Preview graphql module so instead of develop new service and manager i wanted to use preview_graphql.manager but the problem is i'm not in form page and the sendDataFront method and also _preview_graphql_front function need $form and $form_state to work and in my controller i have only access to node entity so.

How to build the $form and $form_state from node entity ?

To get the array $form from node entity it's easy using form builder service:

  $form = \Drupal::service('entity.form_builder')->getForm($node);

But the build of $form_state is more complicated because you should set FormObject, UserInput, and Values :

<?php
use Drupal\Core\Form\FormState;

  // Get edit node form instance.
  /** @var \Drupal\node\NodeForm $form_object */
  $node_form = \Drupal::entityTypeManager()
    ->getFormObject('node', 'default');
  // Set the node as entity.
  $node_form->setEntity($node);
  // Get the node edit form array data (form build).
  $form = \Drupal::service('entity.form_builder')->getForm($node);
  // Collect all fields values.
  $node_fields_values = [];
  foreach ($node->getFields() as $name => $field) {
    $node_fields_values[$name] = $field->getValue();
  }
  // Create new FormState instance.
  $form_state = new FormState();
  // Set form object.
  $form_state->setFormObject($node_form);
  // Set user input.
  $form_state->setUserInput($form);
  // Set values.
  $form_state->setValues($node_fields_values);

Now we have the two arguments we need so we can call _preview_graphql_front like the following

  _preview_graphql_front($form, $form_state);

and let the Preview graphql module do the the work for us ðŸ˜Š