0

I'm looking to prepopulate my endpoints with related data and perform transformation but i'm unsure i've approach this most effectively. I feel like somehow the additional query(s) within the find(...args) being looped is adding to the request and thus hitting performance.

Any advise is much appreciated on how i can perhaps populate in the initial find.

'use strict';

const baseTransformer = require('../../../utils/base-transformer');
const { formatDate, formatTime } = require('../../../utils/datetime');
const { getProperty } = require('../../../utils/props');

/**
 * article service
 */

const { createCoreService } = require('@strapi/strapi').factories;

module.exports = createCoreService('api::article.article', ({ strapi }) => ({
  async find(...args) {
    const { results, pagination } = await super.find(...args);

    const formattedArticles = [];
    for (const result of results) {
      const nextArticleIndex = results.indexOf(result) + 1;
      const nextArticle =
        nextArticleIndex < results.length ? results[nextArticleIndex] : null;

      const populatedResult = await strapi
        .query('api::article.article')
        .findOne({
          where: { id: result.id },
          populate: { tags: true, primary_image: true },
        });

      formattedArticles.push({
        ...baseTransformer(result, 'article'),
        date: formatDate(result.publishedAt),
        time: formatTime(result.publishedAt),
        primary_image: getProperty(populatedResult, 'primary_image', {}),
        article_tags: getProperty(populatedResult, 'tags', []),
        nextArticle,
      });
    }

    const articlesWithNext = formattedArticles.map((result, index) => {
      const nextArticleIndex = index + 1;
      const nextArticle =
        nextArticleIndex < results.length ? results[nextArticleIndex] : null;

      return {
        ...result,
        nextArticle,
      };
    });

    return { results: articlesWithNext, pagination };
  },
  async findOne(...args) {
    const result = await super.findOne(...args);

    return result;
  },
}));
devools
  • 73
  • 6

1 Answers1

0

Well basically args object (that is normally called ctx in koa and so in strapi) contains query key, witch includes populate, so you can pretty much add your default populate directly to it:

const defaultFindArgs = {
  populate: {
    …
  }
}

async find(ctx) {
   const quey = {
        …ctx.query,
        …defaultFindArgs
       };

   const data = await super.find({…ctx, query})
}

P.s. about recommendations, it’s generally recommended to do that type of stuff in middleware (pre populate, transform). E.g. write once use anywhere. But it’s bit more tricky…

antokhio
  • 1,497
  • 2
  • 11
  • 16