1

I have created an API resource which is returning selected subject and categories of the specific tutor by using groupBy method,

the issue is, groupBy method is not sending the response as I am expecting.

Please find the current and expected response below,

Current API response

"Web Design": [
                {
                    "id": 542,
                    "name": "WordPress",
                    "category_name": "Web Design",
                    "pivot": {
                        "tutor_id": 4,
                        "subject_id": 542,
                        "subject_category_id": 70,
                    }
                },
                {
                    "id": 542,
                    "name": "WordPress",
                    "category_name": "Web Design",
                    "pivot": {
                        "tutor_id": 4,
                        "subject_id": 542,
                        "subject_category_id": 70,
                    }
                }
],
"Graphic Design": [
                {
                    "id": 547,
                    "name": "Photoshop",
                    "category_name": "Graphic Design",
                    "pivot": {
                        "tutor_id": 4,
                        "subject_id": 542,
                        "subject_category_id": 71,
                    }
                },
                {
                    "id": 548,
                    "name": "WordPress",
                    "category_name": "Graphic Design",
                    "pivot": {
                        "tutor_id": 4,
                        "subject_id": 542,
                        "subject_category_id": 71,
                    }
                }
]

groupBy Function:

$subjects = $this->tutor->subjects->map(function($subject){
            $subject->category_name = SubjectCategory::find($subject->pivot->subject_category_id)->name;
            return $subject;
        });
        $subjectData = $subjects->groupBy('category_name');

Expected API response

"category": "Web Design",
"subjects": [
                {
                    "id": 542,
                    "name": "WordPress",
                    "category_name": "Web Design",
                    "pivot": {
                        "tutor_id": 4,
                        "subject_id": 542,
                        "subject_category_id": 70,
                    }
                },
                {
                    "id": 542,
                    "name": "WordPress",
                    "category_name": "Web Design",
                    "pivot": {
                        "tutor_id": 4,
                        "subject_id": 542,
                        "subject_category_id": 70,
                    }
                }
],
"category": "Graphic Design",
"subjects": [
                {
                    "id": 547,
                    "name": "Photoshop",
                    "category_name": "Graphic Design",
                    "pivot": {
                        "tutor_id": 4,
                        "subject_id": 542,
                        "subject_category_id": 71,
                    }
                },
                {
                    "id": 548,
                    "name": "WordPress",
                    "category_name": "Graphic Design",
                    "pivot": {
                        "tutor_id": 4,
                        "subject_id": 542,
                        "subject_category_id": 71,
                    }
                }
]

Please find the given migrations for subject categories, subject & subject category table.

Miigration: SubjectCategories

Schema::create('subject_categories', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('slug');
            $table->integer('parent_id')->nullable();
            $table->unsignedTinyInteger('is_deleted')->default(SubjectCategory::IS_DELETED);
            $table->timestamps();
        });

Migration: CreateSubjectsTable

Schema::create('subjects', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('slug');
            $table->integer('isActive');
            $table->timestamps();
        });

Migration: CreateSubjectSubjectCategoryTable

Schema::create('subject_subject_category', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('subject_id')->unsigned();
            $table->integer('subject_category_id')->unsigned();
        });

        Schema::table('subject_subject_category', function($table) {
            $table->foreign('subject_id')->references('id')->on('subjects');
            $table->foreign('subject_category_id')->references('id')->on('subject_categories');
        });

Thanks in advance for help.

1 Answers1

0

The Laravel response is exactly what it's supposed to be when using the groupBy() method on a Collection instance.

Also, your "expected" JSON response is invalid. You cannot use the same property name multiple times, as you will only end up with the last defined values (e.g., the last category property would overwrite the previous category property -- same with subjects). You would need to at the very least group them into their own arrays.

[
    "category": "Web Design",
    "subjects": [...]
],
[
    "category": "Graphic Design",
    "subjects": [...]
],

This output could be achieved through some simple formatting of your query results.

$formatted_response = [];
foreach ($subjectData as $category => $subjects) {
    $formatted_response[] = [
        'category' => $category,
        'subjects' => $subjects
    ];
}
return response()->json($formatted_response);

I hope this helps and good luck!

matticustard
  • 4,850
  • 1
  • 13
  • 18