10

I've got a piece of code I want to reuse. I've read this Laravel cleaner code article and this other Laravel Services Pattern article, where I have realized I can reuse code in several places of the application by using services classes.

In this case, I created a new MyService class, inside a new folder app/Services/MyService.

namespace App\Services;

class MyService
{
    public function reuse_code($param){
       return void;
    }
}

The problem comes when I want to call the class through the constructor inside a Livewire class component, as follows:

<?php

namespace App\Http\Livewire;

use App\Services\MyService;
use Livewire\Component;
use Livewire\WithPagination;

class LivewireTable extends Component
{
    use WithPagination;

    private $myClassService;

    public function __construct(MyService $myService)
    {
        $this->myClassService = $myService;
    }

    public function render()
    {
       $foo = $this->myClassService->reuse_code($param);
       return view('my.view',compact('foo'));
    }
}

The error displayed is the following:

Argument 1 passed to App\Http\Livewire\LivewireTable::__construct() must be an instance of App\Services\MyService, string given

(However, If I use a trait, there are no problems. But I am afraid then my traits collide as previous experiences)

How do I fix it? What am I missing?

2
  • 5
    how are you calling the Livewire class? Have you tried using mount() instead of __construct()? Commented Jan 26, 2021 at 19:54
  • Indeed, in the docs it says so! That did the trick. Thx a lot! Commented Jan 26, 2021 at 20:24

3 Answers 3

10

Solved Just like @IGP said, reading in the livewire docs it says:

In Livewire components, you use mount() instead of a class constructor __construct() like you may be used to.

So, my working code is as follows:

    <?php
    
    namespace App\Http\Livewire;
    
    use App\Services\MyService;
    use Livewire\Component;
    use Livewire\WithPagination;
    
    class LivewireTable extends Component
    {
        use WithPagination;
    
        private $myClassService;
    
        public function mount(MyService $myService)
        {
            $this->myClassService = $myService;
        }
    
        public function render()
        {
           $foo = $this->myClassService->reuse_code($param);
           return view('my.view',compact('foo'));
        }
    }
Sign up to request clarification or add additional context in comments.

2 Comments

Yes when you're inside livewire component you can inject service class using mount() method.
I know this is an old post but I am encountering a similar issue where I load my class in mount just like you however I get the error that the class is called before being initialized.
10

Livewire's boot method Runs on every request, immediately after the component is instantiated, but before any other lifecycle methods are called

Here's the solution worked for me.

public bool $checkAllRecords = false;

public array $checkedRecords = [];

private MailService $service;

public function boot(MailInterface $service)
{
    $this->service = $service;
}

public function updatingCheckAllRecords($value)
{
    $this->checkRecords = $value ? (array) $this->service->getListData($this->perPage, $this->search)->pluck('id') : []
}

Comments

0

Adding a public function boot() method to the component can be useful for things like initializing protected properties, which do not need to be persisted between requests. Below is an example of initializing a protected property as an Eloquent model from the Livewire documentation:

use Livewire\Attributes\Locked;
use Livewire\Component;
use App\Models\Post;
 
class ShowPost extends Component
{
    #[Locked]
    public $postId = 1;
 
    protected Post $post;
 
    public function boot() 
    {
        $this->post = Post::find($this->postId);
    }
 
    // ...
}

See https://livewire.laravel.com/docs/lifecycle-hooks#boot

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.