5

I'm trying to initiate the pagination function in Codeigniter 4 as per the documentation.

$model = new \App\Models\UserModel();

$data = [
    'users' => $model->paginate(10),
    'pager' => $model->pager
];

My controller code is the following:

public function jobmarket() {
    $this->jobs = new \App\Models\Jobs();

    if (!$this->ionAuth->loggedIn())
    {
        return redirect()->to('/logg-inn');
    }

    echo view("dashboard/header", ([
        'ionAuth' => $this->ionAuth,
        'uri' => $this->uri,
    ]));

    echo view("dashboard/jobmarket", ([
        'session' => $this->session,
        'ionAuth' => $this->ionAuth,
        'validation' => $this->validator,
        'jobs' => $this->jobs->paginate(20)->all_jobs(),
        'pager' => $this->jobs->pager()->all_jobs(),
    ]));

    echo view("assets/footer");

}

However, when running this I get the following error:

Argument 1 passed to CodeIgniter\Database\BaseResult::getResult() must be of the type string, null given, called in xxxx/app/vendor/codeigniter4/framework/system/Model.php on line 447

This is my model

public function all_jobs() {
    $this->categories = new \App\Models\Categories();
    $builder = $this->db->table('jobs');
    $builder->select('*');
    $builder->join('users', 'users.id = jobs.jobs_u_id');
    $builder->join('categories', 'category_id = jobs.jobs_category');
    // Make sure to not show current user's listings, since these will show up under "My listings"
    $builder->where('jobs_u_id !=', $this->current_user->id);
    // Check that the listing reflects users chosen categories
    $builder->whereIn('category_id', $this->categories->user_categories());
    $builder->orderBy('jobs_id', 'desc');
    $query =  $builder->get();
    if ($builder->countAllResults() > 0)
    {
        return $query->getResult();

    } else {
        return false;
    }
}

Any help to resolve this would be appreciated.

kanarifugl
  • 9,887
  • 5
  • 29
  • 39
  • Can you try without pagination? Seems the error is regarding the Model and Not pagination itself. Also, your pager implementation may not be correct. I tried the $model->pager but it wasn't working for me so then I changed it to $inventoryModel->pager->getDetails(). Try changing $this->jobs->pager()->all_jobs() to $this->jobs->pager->getDetails() and see if it works out. – Dhaval Chheda Apr 13 '20 at 18:24
  • Also, checkout the pager class from the code. It will give you some idea. But most probably I think your error is related to the model itself. – Dhaval Chheda Apr 13 '20 at 18:26
  • $builder->join('categories', 'category_id = jobs.jobs_category'); Shouldn't it be categories.id or categories.category_id. I suspect category_id is from the users table. Comment out joins and ad them one by one. To see if sql is right print_r($this->db->last_query()); print_r($query) to see result. Run the query in phpmyadmin or mysql developer to see what it returns. – Peter Szalay Apr 28 '20 at 20:49
  • share you Categories model too – Mohammedshafeek C S Apr 29 '20 at 09:46

3 Answers3

3

I don't know where you exactly get this error, but I found a few bugs in your code. Try to fix these bugs, maybe it helps you. Here are the bugs:

  1. The paginate() method returns the result, so it must be the last in your chain. Example: $this->jobs->all_jobs()->paginate(20)
  2. You can get a Pager like this: $this->jobs->pager
  3. If you want to use your all_jobs() method with the paginate() method, you have to return a model in your all_jobs() method

Here is the correct code for your controller:

public function jobmarket() {
    $this->jobs = new \App\Models\Jobs();

    if (!$this->ionAuth->loggedIn())
    {
        return redirect()->to('/logg-inn');
    }

    echo view("dashboard/header", ([
        'ionAuth' => $this->ionAuth,
        'uri' => $this->uri,
    ]));

    echo view("dashboard/jobmarket", ([
        'session' => $this->session,
        'ionAuth' => $this->ionAuth,
        'validation' => $this->validator,
        'jobs' => $this->jobs->all_jobs()->paginate(20),
        'pager' => $this->jobs->pager,
    ]));

    echo view("assets/footer");
}

And here is the correct code for your model:

public function all_jobs() {
    $this->categories = new \App\Models\Categories();
    $builder = $this->db->table('jobs');
    $builder->select('*');
    $builder->join('users', 'users.id = jobs.jobs_u_id');
    $builder->join('categories', 'category_id = jobs.jobs_category');
    // Make sure to not show current user's listings, since these will show up under "My listings"
    $builder->where('jobs_u_id !=', $this->current_user->id);
    // Check that the listing reflects users chosen categories
    $builder->whereIn('category_id', $this->categories->user_categories());
    $builder->orderBy('jobs_id', 'desc');

    return $this;
}

To see the exact place that causes the error try to set CI_ENVIRONMENT = development in your .env file in your root directory. After that try to reload the page where you found this error. You will see a CodeIgniter`s error page with a backtrace. Try to copy all data from backtrace and place here, it helps to understand what exactly is going on.

Oleg Demkiv
  • 1,332
  • 7
  • 7
0

In my case, I had to override findAll() with my own findAll() method, and also check that my specific model extended the Model class of CodeIgniter.

I was basically getting the same error as you @kanarifugl.

So I had something like this:

<?php namespace App\Models;

use CodeIgniter\Model;

class BlogModel extends Model
{
    protected $db;

    public function __construct() 
    {
        parent::__construct();
        $this->db = \Config\Database::connect();
        $this->table = 'Blog';
    }

    public function findAll(int $limit = 12, int $offset = 0)
    {
        $builder = $this->builder();
        $builder->select('*');
        $builder->orderBy('blog_id', 'DESC');
        $builder->join('Categories', 'Categories.category_id = Blog.category_id');

        if ($this->tempUseSoftDeletes === true)
        {
            $builder->where($this->table . '.' . $this->deletedField, null);
        }

        $row = $builder->limit($limit, $offset)
                ->get();

        $row = $row->getResult($this->tempReturnType);

        $eventData = $this->trigger('afterFind', ['data' => $row, 'limit' => $limit, 'offset' => $offset]);

        $this->tempReturnType     = $this->returnType;
        $this->tempUseSoftDeletes = $this->useSoftDeletes;

        return $eventData['data'];
    }
}

And then in my Blog controller I just had this:

<?php namespace App\Controllers;

class Blog extends BaseController
{
    private $blogModel;

    public function __construct() 
    {
        $this->blogModel = new \App\Models\BlogModel();
    }

    public function index()
    {
        $data = [
            'section' => 'blog',
            'articles' => $this->blogModel->paginate(12, 'blog'),
            'pager' => $this->blogModel->pager
        ];
        echo view('articules', $data);
    }
}

And to finish it off, in my view, the part that uses the pager was like this:

<?= $pager->links('blog') ?>

I hope this helps someone.

Mihail Minkov
  • 2,463
  • 2
  • 24
  • 41
0

Remove the constructor function from the Model class to solve the problem

> Argument 1 passed to CodeIgniter\Database\BaseResult::getResult()
> pagination