0

I'm having an issue here where something works just fine on the first 10 results, but when I click on the second pagination, or if I perform a sort that brings the record in question into display, it causes an issue. It basically is a where request to display another record on the same table, and it works with the other records.

I have created different records where they work fine if they are in the first 10 results, but the moment I change them to appear after the pagination break, I get this same error. Otherwise, it works fine if the field is null.

The error it is giving me is that it appears as a non-object, but the code works with every other similar record with the same object selected.

Error

ErrorException (E_ERROR)
Trying to get property 'full_name' of non-object (View: resources/views/doctors/index.blade.php)

<td><?php echo e($doctors->where('id', $doctor->ffs_id)->first()->full_name); ?></td>

Code

@if ($doctor->ffs_id == null)
    <td></td>
@else
    <td>
        {{ $doctors->where('id', $doctor->ffs_id)->first()->full_name }}
    </td>
@endif

Pagination Code: Blade

{{ $doctors->appends([
    'search' => $search,
    'sortColumn' => $sortColumn,
    'sortDirection' => $sortDirection
])->links() }}

Pagination Code: Controller

// Searches, sorts, and filters
$approved = $request->approved;
$search = $request->search;
$sortColumn = ($request->sortColumn == null ? 'last_name' : $request->sortColumn);
$sortDirection = ($request->sortDirection == null ? 'asc' : $request->sortDirection);

$doctors = Doctor::
    when($search, function ($query) use ($search) {
        $query->where(function ($query) use ($search) {
            $query
                ->where('first_name', 'LIKE', '%' . $search . '%')
                ->orWhere('last_name', 'LIKE', '%' . $search . '%')
                ->orWhere('type', 'LIKE', '%' . $search . '%')
                ->orWhere('npi', 'LIKE', '%' . $search . '%')
                ->orWhere('license', 'LIKE', '%' . $search . '%')
                ->orWhere('dea', 'LIKE', '%' . $search . '%');
        });
    })
    ->when($approved, function ($query) use ($approved) {
        $query->where(function ($query) use ($approved) {
            $query->where('is_approved', $approved);
        });
    })
    ->orderBy($sortColumn, $sortDirection)
    ->paginate(10);

Edit: Even removing all of the sort functionality and attempting a load of /doctors?page=2 gives the same error.

Edit 2: I've confirmed that it has something to do with how $doctors is written in the controller. If I create a version of Doctor::all() and reference it in the blade, it pulls up with no errors.

Xerakon
  • 159
  • 1
  • 16
  • 1
    Likely means that `$doctors->where('id', $doctor->ffs_id)->first()` is returning `null`; Are you sure there is a `Doctor` with an `id` of `$doctor->ffs_id`? Also, if you already have `$doctor`, why do you need to filter `$doctors` to find that? Wouldn't `$doctors->where('id', $doctor->ffs_id)->first()` theoretically return the same thing that's already in `$doctor`? Couldn't you just do `$doctor->full_name`? – Tim Lewis Jan 04 '19 at 20:46
  • The `ffs_id` column on a doctor's record references the `id` of another doctor on the doctors table. So I used `$doctors->where('id', $doctor->ffs_id)->first()->full_name` to find the referenced FFS doctor of the $doctor in question. And I don't know why the where statement would return null if it's not returning null when it's on a different page or with no changes to any of the other records on the front page and displaying correctly. – Xerakon Jan 04 '19 at 21:19

1 Answers1

1

You're searching for the parent Doctor record within the original Collection of $doctors returned by the pagination query. If the parent Doctor isn't in the current page of records, your "query" result will be null.

The problem: You have 100 Doctors, with IDs #1-100. You're fetching the first page, so $doctors will contain Doctors #1-10. (Simple example with no searching or anything, just standard pagination.)

Doctor #2 has an ffs_id value of 39. Because you're searching the $doctors collection for a Doctor with ID #39, it won't be found, because $doctors only contains #1-10.

So, you're 100% correct in that the issue is with the contents of $doctors.

Solution: Create an Eloquent relationship method for this Doctor-to-Doctor relationship. Something like this (adjusted to your app's needs):

public function ffs()
{
    return $this->belongsTo(\App\Doctor::class);
}

Use this relationship to retrieve and reference the parent Doctor within your results (bonus sugar here using optional to remove the @if check from the view):

<td>
    {{ optional($doctor->ffs)->full_name }}
</td>

This will directly query the database for the related record, instead of using the $doctors collection.

At this point, we'll run into something called the N+1 problem, where every parent Doctor request will be an individual database query. You can fix this using one of the Eager Loading methods.

Aken Roberts
  • 13,012
  • 3
  • 34
  • 40