Как правильно отправить отсортированную модель из моего контроллера в коллекцию ресурсов API Laravel?

Это мой контроллер:

    public function branchesNearby($lat, $lng)
{

    $branches = Branch::all();

    //Calculate distance between each branch and client
    //Radius of earth is 6371 KM so multiply the result with radius of earth 6371*pi/180
    foreach ($branches as $branch){
    $branch['distance'] = sqrt(pow(($branch->lat - $lat), 2) + pow(($branch->lng - $lng), 2)) * 108;
    }

    //Sort by nearest first
    $sortedBranches = $branches->sortBy('distance');

    return BranchResource::collection($sortedBranches);

}

Вы можете видеть, что я создал дополнительный атрибут для расчета расстояния между местоположением пользователя и местоположением филиала. Затем я сортирую модель ветки по расстоянию. Однако ответ API, который я получаю: ответ API

Вы можете видеть, что это объект. Мне не нужны клавиши "2", "0" и "1". Мне нужно удалить эту дополнительную упаковку, и мне нужно, чтобы это был массив таких объектов: Правильный API но без сортировки Конечно, именно сортировка заставляет его стать объектом? Я пробовал много других способов, один из них:

$sortedBranches = $collection->sortBy('distance');
$final = $sortedBranches->values()->toJson(); 

и отправка этого $final в коллекцию ресурсов. Это дает мне ошибку: «вызов функции-члена first () для строки в ресурсах файлов API». Это должно быть что-то маленькое, но мне действительно нужна помощь.

Обновление: раньше не выкладывал свой Ресурс, вот так:

    public function toArray($request)
    {

        return [
            'id' => $this->id,
            'shop' => $this->shop->name,
            'shop_image' => asset('api/images/' . $this->shop->image_file),
            'lat' => $this->lat,
            'lng' => $this->lng,
            'shop_logo' => asset('api/images/' . $this->shop->logo_file),
            'distance' => $this->distance . " KM"

        ];

Ошибка, которую я получаю, если использую:

$sortedBranches = $branches->sortBy('distance')->values()->all();
   return BranchResource::collection($sortedBranches);

это: Ошибка

Обновление 3:

Если я не вызываю коллекцию ресурсов и просто вывожу $sortedBranches следующим образом:

return response()->json($sortedBranches, 200);

Здесь формат ответа API правильный, но данные неверны. Вот как это выглядит: $sortedBranches

Есть ли способ манипулировать $sortedBranches и показывать результат, как с BranchResource?


person Jawad Chughtai    schedule 08.04.2020    source источник
comment
Я считаю, что вам нужно сделать: $sortedBranches = $branches->sortBy('distance')->values()->all(); Тогда ваш json должен выглядеть как ваше второе изображение :) Если проблема не вызвана вашей последней оболочкой: BranchResource::collection($sortedBranches);. Просто попробуй :)   -  person Rob Biermann    schedule 08.04.2020
comment
значение расстояния также включает «км»? так как ваш контроллер не показывал км. И Вы собираетесь сортировать по расстоянию, которое включает в себя км.   -  person Sachin Kumar    schedule 08.04.2020
comment
Вы должны запрашивать БД по этим значениям (широта, долгота) - не извлекать все, а затем сортировать некоторые из них.   -  person Tpojka    schedule 08.04.2020
comment
@RobBiermann Спасибо за этот ответ. Я тоже пробовал это раньше! Это дает мне ту же ошибку. Вызов функции-члена first() для строки в файлах ресурсов API.   -  person Jawad Chughtai    schedule 08.04.2020
comment
@JawadChughtai Хорошо, эта ошибка указывает на код, который вы опубликовали, или на фрагмент кода, который вы еще не опубликовали?   -  person Rob Biermann    schedule 08.04.2020
comment
@SachinKumar У меня нет расстояния в моей базе данных. Я просто использую значения широты и долготы, хранящиеся в базе данных для каждой ветки, и получаю координаты местоположения пользователей в параметрах получения API для расчета расстояния. Мне нужно вернуть API со списком всех веток, отсортированных по расстоянию до пользователя. Я обновил пост и добавил свою веткуResource где есть КМ   -  person Jawad Chughtai    schedule 08.04.2020
comment
@RobBiermann Эта ошибка относится к библиотеке ресурсов, созданной Laravel. ...\vendor\laravel\framework\src\Illuminate\Http\Resources\CollectsResources.php в строке 24   -  person Jawad Chughtai    schedule 08.04.2020
comment
Я должно быть делаю что-то глупое, но я не могу понять это   -  person Jawad Chughtai    schedule 08.04.2020
comment
@JawadChughtai Спасибо за обновление. Что, если проблема не в части sortBy, а на самом деле в части BranchResource::collect($sortedBranches);. Вы передаете в нее json (строку), я вижу, что это вызывает ошибку, о которой вы говорите. Чем занимается ваш BranchResource? Может быть, оставить его на секунду, чтобы увидеть прямой вывод $sortedBranches?   -  person Rob Biermann    schedule 08.04.2020
comment
@RobBiermann BranchResource позволяет мне манипулировать ответом и делать его именно таким, как я хочу. Позвольте мне опубликовать прямой вывод $sortedBranches, чтобы вы могли увидеть разницу.   -  person Jawad Chughtai    schedule 08.04.2020
comment
@JawadChughtai Спасибо за обновление, я думаю, мы приближаемся. Каков результат BranchResource::collect($sortedBranches); ? Если это коллекция, вам может понадобиться запустить BranchResource::collect($sortedBranches)->values()->all() в конце.   -  person Rob Biermann    schedule 08.04.2020
comment
Вы можете лучше всего проверить это с помощью метода dd(BranchResource::collect($sortedBranches)); или dump(BranchResource::collect($sortedBranches); между прочим.   -  person Rob Biermann    schedule 08.04.2020
comment
@RobBiermann OMG Большое спасибо! Да, я dd() это, и это коллекция. BranchResource::collect($sortedBranches)->values()->all() сделал свое дело :') Это мой первый настоящий проект на laravel, и спасибо за помощь, я думал, что $sortedBranches = $branches->sortBy('distance')->values()->all(); это то же самое, что и BranchResource::collect($sortedBranches)->values()->all()   -  person Jawad Chughtai    schedule 08.04.2020
comment
Np, я опубликую это как ответ, с небольшим объяснением, хорошо? :)   -  person Rob Biermann    schedule 08.04.2020
comment
@RobBiermann Да, отметьте это как ответ с дополнительным объяснением. Определенно поможет и другим!   -  person Jawad Chughtai    schedule 08.04.2020


Ответы (1)


Основываясь на нашем устранении неполадок, результирующее решение должно быть:

return BranchResource::collection($sortedBranches)->values()->all();

Когда вы передаете коллекцию в метод collect класса BranchResource, он воссоздает коллекцию. Laravel видит, что вы возвращаете объект (коллекцию) непосредственно из вашего контроллера, и вмешивается, приводя его к json (я считаю, что это по умолчанию). Если полученный json не преобразуется так, как вы хотите, вам необходимо изменить эту коллекцию. Поэтому нам нужно было изменить коллекцию BranchResource::collection(), а не коллекцию $sortedBranches.

Редактировать:

  • Изменен метод сбора в коллекцию;
person Rob Biermann    schedule 08.04.2020
comment
Небольшое редактирование: return BranchResource::collect($sortedBranches)->values()->all(); на самом деле return BranchResource::collection($sortedBranches)->values()->all(); Плохо, что напечатал неправильно. Спасибо @Rob Biermann еще раз - person Jawad Chughtai; 08.04.2020
comment
Спасибо за отзыв, я изменил ответ :) - person Rob Biermann; 08.04.2020
comment
@JawadChughtai Не могли бы вы проголосовать/пометить ответ, пожалуйста? :D тогда мы квиты ;) - person Rob Biermann; 08.04.2020
comment
Сделанный. Я не могу проголосовать, потому что у меня меньше 15 репутации, но я принял это как ответ :) - person Jawad Chughtai; 09.04.2020