LaravelのResponseで配列を返してそのままそいつをJavaScript側で配列で扱って操作したいというようなことがあると思うのですが、この時にResponseで返す配列はインデックスが揃っていないと(歯抜けが解消されていないと)JavaScript側で受け取ったときにObjectになります。

ちゅーわけでやってみる。なお、コードは動かして試してないので実際には動かないかもしれないがご勘弁を…。

環境


Laravel5.5想定です。

JavaScript側


まず、JavaScript側。Ajaxで/category/AというURIに対してGETリクエストしているものとします。AJaxはaxios使った書き方で書いてます。

1
2
3
4
5
6
7
8
9
10
//axiosで記述
ajax
.get("/category/A")
.then(response => {
//抜けたキーが存在するとObjectとしてforeachできない。
//抜けたキーがない場合は配列扱いになる
response.data.items.forEach(function(x) {
console.log(x.name);
});
});

んで、/category/Aからのレスポンスはサーバから配列が返ってきてそのデータをforEachでぶん回したいとします。ところが、この時にPHP側で配列のインデックスに歯抜けがあった場合に返ってきたデータがObject扱いになってエラーが発生します。

Laravel側


こんな感じのコードだとします。/category/:categoryを呼ぶとルーティングでgetByCategoryが実行されるようになってるという設定です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public function getByCategory(string $category)
{
$collection = collect([]);
$collection->push(collect(["category" => "A", "name" => "P1"]));
$collection->push(collect(["category" => "B", "name" => "P2"]));
$collection->push(collect(["category" => "A", "name" => "P3"]));
$collection->push(collect(["category" => "C", "name" => "P4"]));

//インデックスが歯抜けになったコレクションが出来上がる
$filterd = $collection->filter(function ($v) {
return ($v["category"] === $category);
})

return response(["items" => $filterd]);
}

で、返すコレクション(配列)のインデックスをfilterメソッドで歯抜けにしてみます

こいつを返すとJavaScript側ではitemsがObject扱いとなりforEachできません。ですので、歯抜けをなくします。下記のような感じ。

1
2
3
$filterd = $collection->filter(function ($v) {
return ($v["category"] === $category);
})->values(); //JavaScript側で配列扱いしたければ抜けたキーを詰める

これでJavaScript側でitemsが配列扱いされます。