I'm trying to develop a laravel application that must have an internal API to get always the data and the frontend controllers to consume this API to rendering views. This API will be consumed by mobile apps, so all requests will be handled by the API.
This is my API index action, which is working fine:
public function index(Request $request)
{
$filters = $request->all();
$query = Place::query()->with('user');
if(!isset($filters['filterType']) || !in_array(Str::lower($filters['filterType']), ['and', 'or']) ){
$filters['filterType'] = 'or';
}
//apply filters
foreach($filters as $filter => $value){
if(Place::hasProperty($filter, app(Place::class)->getTable())){
if($filters['filterType'] == 'and'){
$query->where($filter, $value);
}
else{
$query->orWhere($filter, $value);
}
}
}
//sorting
if(!isset($filters['sortOrder']) || !in_array($filters['sortOrder'], ['asc', 'desc'])){
$sortOrder = 'desc';
}
else{
$sortOrder = $filters['sortOrder'];
}
if(isset($filters['sortBy'])){
$sortBy = $filters['sortBy'];
foreach(explode(',', $sortBy) as $sortField){
if(Place::hasProperty($sortField, app(Place::class)->getTable())){
$query->orderBy($sortField, $sortOrder);
}
}
}
//default pagination
if(!isset($filters['maxResults'])){
$filters['maxResults'] = 5;
}
if(!isset($filters['page'])){
$filters['page'] = 1;
}
//apply pagination
$results = $query->paginate($filters['maxResults'], ['*'], 'page', $filters['page']);
$resultsCollectionResource = PlaceResource::collection($results);
return $resultsCollectionResource;
}
If I do this request by postman
What I'm doing wrong? Thanks you all.
EDIT
Based on @matiaslauriti response, I changed my API calling to guzzle:
public function index(Request $request)
{
//$places = redirect()->route('api.places.index', ['request' => $request ])->content();
$response = Http::get(env('API_URL').'/places');
$places = $response->object();
return view('places.index', ['places' => $places]);
}
But I still having exactly the same problem. I tested other methods than $response->object(), like collection. But I never get an object that can use $places->links() method in the view.
CodePudding user response:
$places->links()
This function that you tend to call is a member of Laravel paginator class and $places
should be instance of this class to support this function
if you want to continue with this implementation that you have, and support Laravel pagination features you should make an instance of Laravel lengthawarepaginator and manually create paginator instance.
According to its parameters this might looks something like this:
in your front controller add:
$paginatedPlaces = new LengthAwarePaginator($places->data, $places->meta->total, $places->meta->per_page)
then pass $paginatedPlaces
to your view
the second option that i suggest is that instead of using ->links()
function just simply print out the links property from the response.