how to get total results in laravel pagination? - laravel

I have collection $data=$qwery->paginate();
Further in the loop, I send an api request for each element and receive data, which I use with setAttribute to add to the current element of the collection.
In my blade file, I display the information in the form of a table. The last row of the table should contain the total amount of the field that we added using the api request for all elements on all pages. Can I get all collections of all pages in the controller and then calculate the amount using the standard collection method? I tried to use get() instead of pagination, but the request is taking too long, due to API. I can calculate the amount I need for the current page. But how can I find out the amount for all pages at once? I do not ask for a ready-made solution, just your ideas

Use $data->total() to get the total number of items in your paginated results.
Read more here: https://laravel.com/docs/7.x/pagination#paginator-instance-methods

Related

How to make an API endpoint in Laravel, that can be used to search any table we want?

Background
Let us consider a hypothetical scenario. Suppose we have five different tables in our database,
Customers
Categories
Products
Orders
OderDetails
Our client wants us to add a search bar to the frontend, where a user can search for a specific product and upon tapping the search button, matching products has to be displayed on the frontend.
My Approach for Tackling This Problem
In order to add the aforementioned functionality, I came across the following strategy.
👉 I would add an input box to ender the product name and a submit button.
👉 Upon pressing the submit button, a GET request will be sent to the backend. On the query parameters, the product name that has been entered by the user will be included
👉 Once the GET request is received to the backend, I will pass it down to the ProductsController and from within a method defined inside the ProductController, I will use the Product model to query the products table to see if there are any matching results.
👉 If there are any matching results, I will send them to the frontend inside a JSON object and if there aren't any matching results, I will set a success flag to false inside the JSON object and send it to the frontend
👉 In the frontend, if there are any matching results, I will display them on the screen. Else, I will display "No Results Found!"
Problem with My Approach
Everything works fine if we only want to search the products table. But what if, later our client tells us something like "Remember that search functionality you added for the products? I thought that functionality should be added to orders as well. I think as the list of orders by a user grows and grows, they should be able to search for their previous orders too."
👉 Now, since in our previous approach to search products was implemented in the ProductController using the Product model, when we are adding the same functionality to Orders, WE WOULD HAVE TO DO THE SAME THINGS WE DID IN THE ProductsController AGAIN INSIDE THE OrdersController USING THE Order model. It does not take seconds to understand that this leads to duplication of code.
Problem Summary
❓ How do we add an API endpoint in laravel for a search functionality that can be used to search any table in our database and get results, instead of the search functionality being scoped to a specific controller and a corresponding model?
A good start would be to create a trait called something like searchable and add it to all the models you want to search and put any shared logic between the different models in there. Possibly you'd want to manually allow different columns so in each model you have an array of searchable columns which you'd refer to in your trait.
Your controller would have to point to the related model and call a method in the trait that searches.
As others have pointed out this is a high level question so I won't go too much in detail. Of course there are a million ways to implement this, just try and keep shared logic in place.

Is there a way to convert pagintation to collection/array/json Laravel

Is there a way to convert a pagination to a collection/array to get all items like:
Users::where(...)->paginate(15); //paginated
Output: 15 per page
Users::where(..)->get(); //not paginated
Output: all Users per page
So i is it possible to do something like that:
Users::where(...)->paginate(15)->removePagination();
Wanted output: all Users per page
You have 2 choices:
either retrieve the complete query result by chaining ->get()onto your query.
call ->paginate() to retrieve a pagination instance, which automatically retrieves the first page, and it automatically links the example.com?page=1 url param.
(there are also some other functions that complete the query like ->pluck() or ->value() which might not be applicable to you)
As far as I'm aware you cannot revert to the complete collection instance when you have the pagination retrieved (\Illuminate\Contracts\Pagination\LengthAwarePaginator), nor does it make sense to do so since the idea is to retrieve as little data as possible such that your application stays fast.
Maybe you should explain what you're trying to do; for instance you can retrieve the total count in the paginator using SomeModel::query()->paginate()->total(), among other things. You might not need the complete query after all.

how make a laravel pagination component?

I have a slider component with a back and forward button and I want to get data in sort of pagination how can I do this?
I just want to do this without using Vue.js or livewire just laravel , JS and JQuery.
Laravel's Query Builder provides a paginate method that gives you a LengthAwarePaginator. Normally, you would render this in a blade view with $items->links(), but instead you can convert its result to JSON (https://laravel.com/docs/8.x/pagination#converting-results-to-json). That way you can use the results in JavaScript any way you'd like.
First, why using slider to create a pagination? there are better approach like lazy load, filter column, and simple pagination. lazy load is best for performance i guess.
If you insist to create a slider component, just wondering, how many data that you have? and how many data that you want to retrieve to screen? Imagine, you have more than 1.000.000 rows in your database, you sure wouldn't want to query for them all for real time updates to your screen. Why i tell you 'query them all'?
Let me tell you, if you do a pagination using laravel default pagination (using limit and offset), the flow behind this is like this:
DB will select all of your rows that you have
DB will limit your row depends on limit parameter
DB will scan row one-by-one to match the offset that you want
DB will retrieve the data that you want
With that flow, that's why pagination (limit & offset) is not good enough if you have a lot of data. The solution is change your pagination logic from limit & offset to query like this (case: auto incremental id):
SELECT
*
FROM
payments
WHERE
Id > 15
LIMIT 20
or for descending approach, you can query like this:
SELECT
*
FROM
payments
WHERE
Id < 50
ORDER BY Id DESC
LIMIT 20
Then in laravel, send a json that include a pagination data. So, in javascript you just have to align the pagination data with library or your own pagination logic.

Yii CGridView pagination

I'm using CArrayDataProvider (which is basically a customized query i've created) that returns all the results (over 1000) from the database.
I'm using the results in the view but when i'm using the pagination it's going back to the controller for another query.
my question is: is there any way to move on the the next set of results (already part of the result array) without going to the controller and model again.
*My controller has a fairly advanced function which requires variables and parameters which i dont have in the view when trying to use standard AJAX request for the next page.
thanks,
Danny
my question is: is there any way to move on the the next set of
results (already part of the result array) without going to the
controller and model again
Then my answer would be NO if you was using CGridview's pagination. In your situation, you have to make the pagination by yourself instead. You have already selected all of records, and would like to manipulate them on your client side, you really don't need the pagination of CGridview at all.
Pushing all of records into a page on first load is not good idea, but maybe your requirement has asked, I just say that.

dashboard timeline

I'm trying to implement a dashboard similar to facebook in cakephp (getting posts and post them to timeline and while you press see more it keeps retrieving posts from previous offsets) , but im still confused about the logic and tools , should i use the cakephp pagination class in my implementations.
$this->paginate();
it somehow should be called through ajax accourding to some performance wise
Any helps or suggestions where to start from ?
Thanks All
Don't use paginate
If you paginate something that you are prepending data to - you're going to get data overlapping such that you ask for page 2 - and get the end of, as far as the current user is concerned, the previous page.
Use a timestamp
The normal technique for an endless stream of data is to use a query like:
SELECT *
FROM foos
WHERE created >= $previousLastTimestamp
ORDER BY created DESC
LIMIT 20
Note that while I'm using created in this example - it can be any field that is pseudo unique.
When you first render the page, store the timestamp of the last entry in a javascript variable, then your "get more posts" logic should be:
Make an ajax (get) request, passing the last timestamp
Perform the above sql query (as a $this->Foo->find call)
in your js update the last timestamp so that you know where you are up to for the next time the user clicks "get more posts"
The reason to use a >= condition is that, unless the field you are testing against has unique values, it's possible for there to be multiple rows with the value you're testing for. If you have a naturally-unique field that you are sorting by (id) then you don't need to use greater-or-equal, you can simply use greater-than, and avoid needing to think about duplicate rows.
Here's a reference which explains in more detail why you should handle systems like this avoiding traditional pagination.

Resources