Use not public properties

I have a component to edit some properties of a model. I don’t want to make the whole model public, so i only set the needed fields public (because it contains some sensitive data). However, I get the model via the mount() method. In another method, I save the settings. The thing where I am stuck is that I cant figure out how to save the model via the mount method so that I can access it in the save method without storing the model in a public property.

Here is my component, it works if the $company property is public. However, how do I hide the $company from the javascript?

class General extends Component
{

    public $company;
    public $companyArray;

    public function saveCompany()
    {
        $validated = $this->validate([
            'companyArray.street' => 'required|string',
            'companyArray.house_number' => 'required|string',
            'companyArray.zip' => 'required|digits:5',
            'companyArray.city' => 'required|string'
        ]);

        $this->company->update($validated['companyArray']);

    }

    public function mount(Company $company)
    {
        $this->company = $company;
        $this->companyArray = [
            'street' => $this->company->street,
            'house_number' => $this->company->house_number,
            'zip' => $this->company->zip,
            'city' => $this->company->city
        ];
    }

    public function render()
    {
        return view('livewire.company.edit.general');
    }
}

You could just have the $company->id as a public property public $companyId and in the saveCompany method do an Eloquent find on the model.

class General extends Component
{

    public $companyId;
    public $companyArray;

    public function saveCompany()
    {
        $validated = $this->validate([
            'companyArray.street' => 'required|string',
            'companyArray.house_number' => 'required|string',
            'companyArray.zip' => 'required|digits:5',
            'companyArray.city' => 'required|string'
        ]);

        $company = App\Company::find($this->companyId);

        $company->update($validated['companyArray']);
    }

    public function mount(Company $company)
    {
        $this->companyId = $company->id;

        $this->companyArray = [
            'street' => $this->company->street,
            'house_number' => $this->company->house_number,
            'zip' => $this->company->zip,
            'city' => $this->company->city
        ];
    }

    public function render()
    {
        return view('livewire.company.edit.general');
    }
}

You don’t need to change anything, livewire already automatically does what @ashleyhood suggested to do manually. Eloquent model properties are not accessible by javascript, and livewire automatically hydrates them for you on the backend component. The only properties that will be in javascript are the ones in your array.

1 Like

Thanks for that explanation. However, one Question: Does this mean, that the user can easily change the company_id via js and then has access to another company?

Well they can try, but the page will error out. Say your current company id is 1, and you change it in the console to 2:
livewire.components.componentsById.{generatedLivewireIdString}.data.company.id = 2

As soon as another request is made by livewire it will fail to a 500 error for the user, and you will see this error in your logs:
Livewire encountered corrupt data when trying to hydrate the [general] component. Ensure that the [name, id, data] of the Livewire component wasn't tampered with between requests.

2 Likes