trifek's avatar

Error in Laravel Too few arguments to function

Hi, I am beginner in php and Laravel. I use in my project Laravel 7. I have repository pattern in my project with cache.

PageServiceProvider:

public function register()
{
    $this->app->bind(PageRepositoryInterface::class, function ($app) {
        return new CachingPageRepository(
            new PageRepository
        );
    });
}

public function provides()
{
    return [
        PageRepositoryInterface::class,
    ];
}

CachingBaseRepository:

abstract class CachingBaseRepository implements RepositoryInterface
{
    use ScopeActiveTrait;

    protected $model;

    public function all()
    {
        return Cache::remember($this->model.'.all', $minutes = 10, function () {
            return $this->model->get();
        });
    }

    public function allEnables()
    {
        return Cache::remember($this->model.'.enables', $minutes = 10, function () {
            return $this->model->active()->get();
        });
    }

    public function list(string $orderByColumn, string $orderBy = 'desc', array $with = [])
    {
        return Cache::remember($this->model.'.list', $minutes = 10, function () use($with, $orderByColumn, $orderBy) {
            return $this->model->with($with)
                ->orderBy($orderByColumn, $orderBy)
                ->get();
        });
    }

    public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
    {
        return Cache::remember($this->model.'.listWithPaginate', $minutes = 10, function () use($with, $orderByColumn, $orderBy, $perPage) {
            return $this->model->with($with)
                ->orderBy($orderByColumn, $orderBy)
                ->paginate($perPage)->appends(request()->query());
        });
    }

    public function create(array $data): int
    {
        return $this->model->create($data)->id;
        // delete cache: all, enables, list, listWithPaginate
    }

    public function update(array $data, int $id, string $attribute = 'id'): void
    {
        $this->model->where($attribute, '=', $id)->update($data);
        // delete cache: all, enables, list, listWithPaginate
    }

    public function delete(int $id): void
    {
        $this->model->destroy($id);
        // delete cache: all, enables, list, listWithPaginate
    }

    public function find(int $id)
    {
        return Cache::remember($this->model.".{$id}", $minutes = 60, function () use ($id) {
            return $this->model->find($id);
        });
    }

    public function getModel()
    {
        return Cache::remember($this->model.".all", $minutes = 60, function (){
            return $this->model;
        });
    }

    public function getFirst(int $id)
    {
        return Cache::remember($this->model.".{$id}", $minutes = 60, function () use ($id) {
            return $this->model->where('id', $id)->first();
        });
    }

    public function findOrFail(int $id)
    {
        return Cache::remember($this->model.".{$id}", $minutes = 60, function () use ($id) {
            return $this->model->findOrFail($id);
        });
    }
}

BaseRepository:

abstract class BaseRepository implements RepositoryInterface
{
    use ScopeActiveTrait;

    protected $model;

    public function all()
    {
        return $this->model->get();
    }

    public function allEnables()
    {
        return $this->model->active()->get();
    }

    public function list(string $orderByColumn, string $orderBy = 'desc', array $with = [])
    {
        return $this->model->with($with)
            ->orderBy($orderByColumn, $orderBy)
            ->get();
    }

    public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
    {
        return $this->model->with($with)
            ->orderBy($orderByColumn, $orderBy)
            ->paginate($perPage)->appends(request()->query());
    }

    public function create(array $data): int
    {
        return $this->model->create($data)->id;
    }

    public function update(array $data, int $id, string $attribute = 'id'): void
    {
        $this->model->where($attribute, '=', $id)->update($data);
    }

    public function delete(int $id): void
    {
        $this->model->destroy($id);
    }

    public function find(int $id)
    {
        return $this->model->find($id);
    }

    public function getModel()
    {
        return $this->model;
    }

    public function getFirst(int $id)
    {
        return $this->model->where('id', $id)->first();
    }

    public function findOrFail(int $id)
    {
        return $this->model->findOrFail($id);
    }
}

PageRepository:

class PageRepository extends BaseRepository implements PageRepositoryInterface
{

    public function __construct(Page $model)
    {
        $this->model = $model;
    }


    public function search(string $query, string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
    {
        return $this->model->where('title', 'LIKE', '%' . $query . '%')->orWhere('description', 'LIKE', '%' . $query . '%')->orWhere('keywords', 'LIKE', '%' . $query . '%')->orWhere('content', 'LIKE', '%' . $query . '%')->with($with)->orderBy($orderByColumn, $orderBy)->paginate($perPage)->appends(request()->query());
    }

    public function getTextPageFromSlug(string $slug)
    {
        return $this->model->active()->where('slug', $slug)->first();
    }

}

CachingPageRepository

class CachingPageRepository extends CachingBaseRepository implements PageRepositoryInterface
{
    public function __construct(Page $model)
    {
        $this->model = $model;
    }


    public function search(string $query, string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
    {
        return Cache::remember('page.all', $minutes = 10, function () use($query, $orderByColumn, $with, $orderBy, $perPage) {
            return $this->model->where('title', 'LIKE', '%' . $query . '%')->orWhere('description', 'LIKE', '%' . $query . '%')->orWhere('keywords', 'LIKE', '%' . $query . '%')->orWhere('content', 'LIKE', '%' . $query . '%')->with($with)->orderBy($orderByColumn, $orderBy)->paginate($perPage)->appends(request()->query());
        });
    }


    public function getTextPageFromSlug(string $slug)
    {
        return Cache::remember("users.{$slug}", $minutes = 60, function () use ($slug) {
            return $this->model->active()->where('slug', $slug)->first();
        });
    }
}

PageRepositoryInterface:

interface PageRepositoryInterface extends RepositoryInterface
{

    public function search(string $query, string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 30);


    public function getTextPageFromSlug(string $slug);

}

I want to add cache to my website in the above code. My controller looks like this:

protected $model;


    public function __construct(PageRepositoryInterface $repository)
    {
        $this->model = $repository;
    }


    public function index(Request $request)
    {
        if ($request->input('query') != "") {
            $pages = $this->model->search($request->input('query'), 'id', 'asc', [],  30);
        } else {
            $pages = $this->model->listWithPaginate('id', 'desc', [],  30);
        }
        return view('admin.pages.list', ['pages' => $pages]);
    }

When I run the above code I get the error:

ArgumentCountError Too few arguments to function App\Repositories\PageRepository::__construct(), 0 passed in /var/www/app/Providers/PageServiceProvider.php on line 22 and exactly 1 expected

Earlier, when I didn't have the cache on the page, my PageServiceProvider looked like this:

public function register()
    {
        $this->app->bind(
            PageRepositoryInterface::class,
            PageRepository::class
        );
    }

And the code ran without problems.

How can I repair it?

Please help me.

0 likes
12 replies
MichalOravec's avatar
public function register()
{
    $this->app->bind(PageRepositoryInterface::class, function ($app) {
        return new CachingPageRepository(
            new PageRepository // problem is here
        );
    });
}

You have add there Page model

new PageRepository(new Page)

Because your PageRepository has constructor

public function __construct(Page $model)
{
    $this->model = $model;
}

By the way, I really don't understand why people want to use repository, with eloquent I think it's not necessary.

1 like
trifek's avatar

Thank you very much for your answer.

You suggest to replace:

new PageRepository

on:

new PageRepository (new Page)

?

If so, this change causes an error::

Argument 1 passed to App\Repositories\Caching\CachingPageRepository::__construct() must be an instance of App\Models\Page, instance of App\Repositories\PageRepository given, called in /var/www/app/Providers/PageServiceProvider.php on line 23```
trifek's avatar

"By the way, I really don't understand why people want to use repository, with eloquent I think it's not necessary."

I am taking a course and recommend using a repository

piljac1's avatar

CachingPageRepository currently takes a Page instance as an argument within the constructor. You probably want a PageRepository instead.

Snapey's avatar

import the page model class

Your code us unnecessarily complicated, but understand if its for an assignment

trifek's avatar

Yes, it's help. Thank you all for your help!!! :). Now have error:

public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
    {
        return Cache::remember($this->cacheKey.'.listWithPaginate', $minutes = 10, function () use($with, $orderByColumn, $orderBy, $perPage) {
            return $this->model->with($with)
                ->orderBy($orderByColumn, $orderBy)
                ->paginate($perPage)->appends(request()->query());
        });
    }

in line: return $this->model->with($with)

Error:

Call to undefined method App\Repositories\PageRepository::with()

Why it's not work ?

MichalOravec's avatar
Level 75

Did you read that error message?

You call there with on model.

$this->model->with($with)

But your PageRepository or CachingBaseRepository doesn't have with method.

trifek's avatar

I am try this this combination:

class CachingPageRepository extends CachingBaseRepository implements PageRepositoryInterface
{
    public function __construct(PageRepositoryInterface $model)
...
}

and:

class CachingPageRepository extends CachingBaseRepository implements PageRepositoryInterface
{
    public function __construct(PageRepository $model)
...
}

In each case the same error

trifek's avatar

Yes, I read error messages :)

Page repository extends BaseRepository. In BaseRepository i have:

public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
    {
        return $this->model->with($with)
            ->orderBy($orderByColumn, $orderBy)
            ->paginate($perPage)->appends(request()->query());
    }

CacheBaseRepository has:

public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
    {
        return Cache::remember($this->cacheKey.'.listWithPaginate', $minutes = 10, function () use($with, $orderByColumn, $orderBy, $perPage) {
            return $this->model->with($with)
                ->orderBy($orderByColumn, $orderBy)
                ->paginate($perPage)->appends(request()->query());
        });
    }

Before adding the cache, BaseRepository worked in its current form

trifek's avatar

I found problem. I make debug:

public function listWithPaginate(string $orderByColumn, string $orderBy = 'desc', array $with = [], int $perPage = 10)
    {
...
dd($this->model);
...
}

When I have in ServiceProvider:

public function register()
    {
        $this->app->bind(
            PageRepositoryInterface::class,
            PageRepository::class
        );
    }

my debug return:

App\Models\Page {#348 ▼
  #quarded: array:1 [▶]
....

When I have new ServiceProvider

public function register()
    {
        $this->app->bind(PageRepositoryInterface::class, function ($app) {
            return new CachingPageRepository(
                new PageRepository(new Page())
            );
        });
    }

    public function provides()
    {
        return [
            PageRepositoryInterface::class,
        ];
    }

my debug return:

App\Repositories\PageRepository {#343 ▼
  #model: App\Models\Page {#344 ▼
    #quarded: array:1 [▶]
    #fillable: array:6 [▶]
trifek's avatar

the solution with is problem was change $this->model:

class CachingCategoryRepository extends CachingBaseRepository implements CategoryRepositoryInterface

{
    public function __construct(CategoryRepositoryInterface $model)
    {
        $this->model = $model->getModel();
        $this->cacheKey = 'category';
        $this->cacheTime = 3600;
    }
}
trifek's avatar

thank you very much for your's help :)

Please or to participate in this conversation.