Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

talentedaamer's avatar

Property [id] does not exist on this collection instance

When I return custom array from Grade Resource it works fine. But when i return same custom array instead of parent::toArray($request) from GradeCollection it gives above on first key of the array. Following is the code i am using.

API Routes

Route::namespace('Api\v1')->prefix('v1')->group(function () {
    Route::get('exams', 'ExamController@index')->name('api.v1.exams.index');
    Route::get('exams/{id}', 'ExamController@show')->name('api.v1.exams.show');
    Route::get('exams/{id}/grades', 'ExamController@gradesShow')->name('api.v1.exams.grades.index');
});

Grade Model

namespace App\Models;
use Illuminate\Database\Eloquent\Model;

class Grade extends Model
{
    protected $fillable = [
        'grade_name', 'grade_section', 'teacher_id'
    ];
    
    public function teacher()
    {
        return $this->belongsTo('\App\Models\Teacher');
    }
    
    public function students()
    {
        return $this->hasMany('\App\Models\Student');
    }
    
    public function exams()
    {
        return $this->belongsToMany('\App\Models\Exam');
    }
}

Grade Resource : works fine

namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;

class Grade extends JsonResource
{
    public function toArray($request)
    {
        // return parent::toArray($request);
        return [
            'id' => $this->id,
            'name' => $this->grade_name,
            'section' => $this->grade_section,
        ];
    }
}

GradeCollection : produces subject error

namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\ResourceCollection;

class GradeCollection extends ResourceCollection
{
    public function toArray($request)
    {
        // return parent::toArray($request);
        return [
            'id' => $this->id,
            'name' => $this->grade_name,
            'section' => $this->grade_section
        ];
    }
}

GradeController

namespace App\Http\Controllers\Api\v1;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Grade;
use App\Http\Resources\Grade as GradeResource;
use App\Http\Resources\GradeCollection;
use App\Http\Resources\StudentCollection;

class GradeController extends Controller
{
    public function index()
    {
        $grades = Grade::all();
        return new GradeCollection($grades);
    }

    public function show($id)
    {
        $grade = Grade::find($id);
        return new GradeResource($grade);
    }

    public function studentsShow($id)
    {
        $grade = Grade::find($id);
        return new StudentCollection($grade->students);
    }
}
0 likes
5 replies
Snapey's avatar

try

    public function index()
    {
        $grades = Grade::get();
        return new GradeCollection($grades);
    }
mvd's avatar
mvd
Best Answer
Level 48

@talentedaamer it's because in $grades there are (or there can be) mutliple items

What you can do is

class GradeCollection extends ResourceCollection
{
    public function toArray($request)
    {
       // return parent::toArray($request);
    $grades = array();
    foreach ($this->resource as $grade) {
        $grades[] = array(
            'id' => $grade->id,
            'name' => $grade->grade_name,
            'section' => $grade->grade_section
        );
    }
    return $grades;
    }
}

But if you want the grades just in a array format you can also do this in your controller

return Grade::select('id', 'grade_name as name', 'grade_section as section')->get()->toArray();

1 like
ronssij's avatar

What I found was you never have to loop the collection if you want it.

In my case, I have an event collection. What I did was this.

php artisan make:resource Event

php artisan make:resource EventCollection

In the Event

return [
  "id"        => $this->id,
  "title"     => $this->title,
  "parent_id" => $this->parent_id,
  "color"     => $this->color,
  "start"     => $this->start_date,
  "end"       => $this->end_date
];

and in the EventCollection just leave it as is:

return parent::toArray($request);
1 like
talentedaamer's avatar

what if you want to show only event title, and start_date?

1 like

Please or to participate in this conversation.