I have a form, which contains an additional field. And I want to initiate the field via the form constructor.

class ServicesForm extends FormBase {

    private $service_type;

    public function __constructor($_service_type){
        $this->service_type = $_service_type;

The form is created in a controller.

class ServicesController extends ControllerBase {

    public function getServices($service_type){
        $data['form'] = \Drupal::formBuilder()->getForm('\Drupal\palom_services\Form\ServicesForm');

        return $data;

Could you clarify me, how to pass the parameter $service_type to the form inside the controller method ?

Maybe, should I do it without FormBuilder and getForm ?

2 Answers 2


Just add it to your form's buildForm method signature:

public function buildForm(array $form, FormStateInterface $form_state, $arg = NULL) {
  // Use $arg

Then literally pass it to the form builder's getForm method:

$data['form'] = \Drupal::formBuilder()->getForm('\Drupal\palom_services\Form\ServicesForm', $service_type);

I have tried the Clive's solution, however, it breaks the interface of FormInterface.

In the \Drupal::formBuilder()->getForm() method, the code is the following:

  public function getForm($form_arg) {
    $form_state = new FormState();

    $args = func_get_args();
    // Remove $form_arg from the arguments.
    $form_state->addBuildInfo('args', array_values($args));

    return $this->buildForm($form_arg, $form_state);

So you don't need to modify the signature of buildForm(), you should access these values from $form_state.

It should be usable this way: $form_state->getBuildInfo()['args']

  • Really good and clean method.
    – Christian
    Commented Oct 24, 2019 at 0:40

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.