3

I'm trying to use a constructor inside my CreateLeadRequest class, but it seems to be failing.

class CreateLeadRequest extends FormRequest
{
    private $dealer;
    public function __construct() {
       parent::__construct();
       $this->dealer = Dealer::findOrFail($this->dealer_id);
    }
}

$this->dealer_id is coming in as null. I can use it inside prepareForValidation and other functions just fine, so why is it coming in as null inside the constructor?

farjam
  • 2,089
  • 8
  • 40
  • 77
  • 2
    the FormRequest class doesn't get filled with values until after it is initialized (when resolved from the IoC container) [ `Request@createFrom`] – lagbox Feb 06 '23 at 20:21
  • correction ... "... filled with values until after it is instantiated" – lagbox Feb 07 '23 at 01:42
  • So is it possible to set a property and re-use it in there without using a constructor? – farjam Feb 07 '23 at 19:07
  • Override the `initialize` function. Just make sure to call the `parent::initialize` first with all of the arguments passed in. Then you should be able to load the Dealer object after – andrewtweber Feb 07 '23 at 20:14
  • is there a particular reason this FormRequest needs a Dealer instance? – lagbox Feb 09 '23 at 01:52
  • @lagbox I can probably get away with it. I ended up getting the dealer object inside my `withValidator` function and just passing it as an argument inside my other functions that do various validations. Previously I was getting the dealer object separately inside each validation function. – farjam Feb 09 '23 at 05:26

1 Answers1

0

This issue related to the timing When the constructor is being called in relation to the assignment of the $this->dealer_id property. When constructor is called then object is instantiated, but at that point, the properties of the object haven't been assigned values yet.

In Laravel's form requests, the constructor is typically called before the request data is bound to the object's properties. So you're getting null for $this->dealer_id inside the constructor.

You can consider using the boot() method instead of the constructor. The boot() method is automatically called by Laravel after the request object has been created and the request data has been bound to its properties.

you can update you code:

class CreateLeadRequest extends FormRequest
{
    private $dealer;
    
    public function boot()
    {
        $this->dealer = Dealer::findOrFail($this->dealer_id);
        parent::boot();
    }
    
    // ........ rest of your code
}

By moving your logic to the boot() method, you ensure that $this->dealer_id has been assigned a value before you try to retrieve the Dealer instance.

tec
  • 5
  • 6