Hi! I’m trying to get all the records from one collection. What’s your best approach?
Thanks in advance
Hi! I’m trying to get all the records from one collection. What’s your best approach?
Thanks in advance
It’s all in the docs:
Sorry maybe I didn’t explain it well. I mean without limits. Thanks
I have sorted that by creating custom APIs in collection folders. That will help you get the data the way you wanted.
This may not be exactly what you’re looking for, but I changed my api.js in the config folder to increase the maximum pageSize to a very high number (i.e. 1000), which you could also set as the defaultLimit if you wanted.
module.exports = {
rest: {
defaultLimit: 25,
maxLimit: 1000,
withCount: true,
},
};
I think what they mean is they do not want to have to use populate
everywhere and deeply nested and convoluted queries to get things like images and such. If we wanted pieces of data, we’d use GraphQL. I have no idea how to do as I just started and am looking for the answer myself.
Instead of this: GET /api/articles/:id?populate[0]=seoData&populate[1]=seoData.sharedImage&populate[2]=seoData.sharedImage.media
We’d like to do: GET /api/articles/
And just get the entire collection from that request.
Found this: strapi-plugin-populate-deep - npm
Works great and its pretty simple as well if you wanna just clone it and add it directly to your project if you need something custom
That simple question should have a lot of answers.
Strapi does not recommand to do that - it might be heavy if you have a lot of records.
Anyway, a lot of users do need it.
Here’s my solution. In this example, the content type is area.
I override the find
function in the controller.
If the query has its parameter pagination.page=-1
, it’s a flag that we want ALL the records.
This solution is handly because you don’t need to create an extra route (eg. api/area/all), but you could if you want: the main idea is that we have a new service method findAll
.
src/api/area/services/area.ts :
import { fetchAllEntries } from '../../../utils/fetchAllEntries'
export default factories.createCoreService('api::area.area', ({strapi}) => ({
async find(params) {
//get ALL items
if (params?.pagination?.page === '-1') {
return this.findAll(params);
}
// Calling the default core controller
return await super.find(params);
},
async findAll(params) {
return fetchAllEntries('api::area.area',params);
},
Rather than overriding the find
method in the service, I would prefer use a middleware for this, but well, I haven’t find a way to achieve it.
src/utils/fetchAllEntries.ts:
export async function fetchAllEntries(type, query:any = {}) {
const maxLimit = strapi.config.get('api.rest.maxLimit', 25);
let allItems = [];
let iterations = 0;
let totalPages = 1;
let pagination = {} as any;
//If pagination was set
delete query.pagination;
do {
// Fetch entries with pagination
const response = await strapi.service(type).find({
...query,
pagination:{
page:iterations+1,
pageSize:maxLimit
}
});
allItems = [...allItems, ...response.results];
if (response.pagination){
pagination = {...response.pagination};
totalPages = pagination.pageCount;
}
console.info(`fetchAllEntries ${type}... ${iterations+1}/${pagination.pageCount}`);
iterations++;
} while (iterations < totalPages);
delete pagination.page;//we'll return all results so page is not a relevant info
return {
results:allItems,
pagination:pagination
};
}