2

I am generating an an array of categories and subcategories in my Laravel API for use in my client side app.

I'm doing this by using the collection's filter and map methods to organize the data pulled from the database:

// get the data from the category table
$categoryData = $categories->all()->categories();

// filter the data by category names we know we want and create the multi-dimensional array of the fields we need
$categoryList = $categoryData->filter(function ($value) {
    return $value['Category'] == "by Area of Interest" || $value['Category'] == "by Grade Level";
})
->map(function ($value) {
    return ['category' => $value['Category'], 'subCategory' => $value['Subcategory']];
});

dd($categoryList);

When I review the die and dump result, I get my collection with it's array of correctly formatted items:

dd result

And if I output it as an array with:

dd($categoryList->toArray());

I see the multi-dimensional array I would expect.

dd result when outputting as an array

The problem I'm running into is when I try to output it as json for my client app to consume.

dd($categoryList->toJson());

If I output as json I get an object that contains the php array indexes as properties and the php sub arrays as objects assigned to those properties.

dd result when outputting to json

What I want is a json object that contains an array of objects. e.g.

$categoryList = [['category' => 'test', 'subCategory' => 'test'], ['category' => 'test', 'subCategory' => 'test']];
dd(json_encode($categoryList));

Which outputs:

example of what I want

Is there something I'm doing wrong with my collection calls?

Update

Per Hognbin's comment:

The call to $categories->all()->categories(); returns a collection of category data that I then manipulate to get my list.

$categoryData = $categories->all()->categories();
dd($categoryData);

yields:

result of categories->all()

Chris Schmitz
  • 20,160
  • 30
  • 81
  • 137
  • I think the problem is in $categories->all()->categories(), can you show the code of categories() ? – Hongbin Wang Apr 25 '16 at 19:38
  • I updated my post. I didn't add the code from the categories method because while it's output is relevant to the problem, it's code isn't; the output is the starting data I'm working with. – Chris Schmitz Apr 25 '16 at 19:44
  • You have tried something like this: $return = $categoryList->toArray() return Response::json($return, 200, [], JSON_NUMERICK_CHECK); – Carlos Arauz Apr 25 '16 at 19:47
  • Possible duplicate of [PHP Array to JSON Array using json\_encode();](http://stackoverflow.com/questions/11722059/php-array-to-json-array-using-json-encode) – Hongbin Wang Apr 25 '16 at 19:55
  • @HongbinWang, similar, but different because this one specifically centers around laravel's Collection class. – Chris Schmitz Apr 26 '16 at 00:40

1 Answers1

2

The problem is that the indexes are the ids of categories which You'll get from eloquent collection when You try to make array from it.

If you want to have a clean array of objects, I suggest doing this:

json_encode(array_values($categoryList->toArray()));

Final implementation by Chris

The above explanation and function calls got me the end result I needed. After confirming it worked via these function calls I looked at the Collection class methods to see how I could implement it using the class. Here's what I did:

$categoryList = $categoryData->filter(function ($value) {
    return $value['Category'] == "by Area of Interest" || $value['Category'] == "by Grade Level";
})
->map(function ($value) {
    return ['category' => $value['Category'], 'subCategory' => $value['Subcategory']];
})
->values()
;

If you look at the Collection class' values() method, it's doing the same thing:

values method in Collection class

Since the Laravel Collection items are stored as an array, the toArray() method call is not needed.

Laurel
  • 5,965
  • 14
  • 31
  • 57
Filip Koblański
  • 9,718
  • 4
  • 31
  • 36
  • Ah thank you! This definitely gets me what I need. I ended up implementing it a bit differently (it's using the methods for the laravel collection class to make it fit the rest of the functional chaining), but the only reason I was able to put that chain together was from seeing this comment and figuring out how to do it via laravel's collection class. I'm going to edit your answer just so you can see your original answer and the way I ended up adding it into my code.Thanks for the help! – Chris Schmitz Apr 25 '16 at 19:54
  • @Filip Koblański Maybe you can help me. Look at this : https://stackoverflow.com/questions/51488623/how-can-i-convert-array-two-dimensional-to-collection-laravel – moses toh Jul 24 '18 at 02:52