Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

populateCreatorFields not working in Strapi v4 #12228

Closed
vandrieu opened this issue Jan 18, 2022 · 13 comments
Closed

populateCreatorFields not working in Strapi v4 #12228

vandrieu opened this issue Jan 18, 2022 · 13 comments
Labels
issue: bug Issue reporting a bug severity: medium If it breaks the basic use of the product but can be worked around source: core:strapi Source is core/strapi package status: pending reproduction Waiting for free time to reproduce the issue, or more information

Comments

@vandrieu
Copy link

vandrieu commented Jan 18, 2022

Bug report

Describe the bug

Creator fields are not returned by Strapi V4 REST API even when populateCreatorFields is set to true.

Steps to reproduce the behavior

  1. Install Strapi v4
  2. Start the server using npm run develop
  3. Using Strapi admin panel, create a collection type with a name field
  4. Add an entry manually using the admin panel GUI
  5. Allow the collection to be queried through the public API (settings > roles and permissions > Public > add find and findOne on your collection and save)
  6. Query the data using the REST API
  7. Creator fields are not shown which is normal as per the V4 docs since populateCreatorFields is false by default: https://docs.strapi.io/developer-docs/latest/development/backend-customization/models.html#model-options
  8. Change the options in src/api/<collection>/content-types/<collection>/schema.json to the following:
{
  "kind": "collectionType",
  //...some configs
  "options": {
    "privateAttributes": ["name"],
    "populateCreatorFields": true
  },
  1. Make sure the server restarts or restart it
  2. Query the API again

Expected behavior

name field is not returned anymore
created_by field is returned

Actual behavior

name field is not returned anymore
created_by field is not returned

System

  • Node.js version: v14.18.2
  • NPM version: 6.14.13
  • Strapi version: 4.0.4
  • Database: sqlite
  • Operating system: MacOS
@derrickmehaffy derrickmehaffy added issue: bug Issue reporting a bug severity: medium If it breaks the basic use of the product but can be worked around source: core:strapi Source is core/strapi package status: pending reproduction Waiting for free time to reproduce the issue, or more information labels Jan 18, 2022
@redakzter01
Copy link

some workaround?

@niwasmala
Copy link

Here is some workaround. It doesn't need to set "populateCreatorFields" options. You can use strapi db query and ask to populate createdBy field.

If you use Graphql API, you need to extend the query you want

// path: ./src/index.js

module.exports = {
  register({ strapi }) {
    const extensionService = strapi.plugin('graphql').service('extension');

    const extension = ({ nexus }) => ({
      types: [
        // creating new object type called Creator
        nexus.objectType({
          type: 'Creator',
          name: 'Creator',
          definition(t) {
            t.int('id');
            t.string('firstname');
            t.string('lastname');
          },
        }),
        nexus.extendType({
          type: 'Article',
          definition(t) {
            // we want to know who is the creator
            t.field('createdBy', {
              type: 'Creator',
              async resolve(root, args, ctx) {
                // when we use query, we can populate createdBy
                const query = strapi.db.query('api::article.article');
                const article = await query.findOne({
                  where: {
                    id: root.id,
                  },
                  populate: ['createdBy'],
                });
                
                return {
                  id: page.createdBy.id,
                  firstname: page.createdBy.firstname,
                  lastname: page.createdBy.lastname,
                };
              },
            })
          }
        }),
      ],
    });

    extensionService.use(extension);
  }
}    

When I query articles, I can ask for the createdBy

query {
  articles {
    data {
      attributes {
        createdBy {
          id
          firstname
          lastname
        }
      }
    }
  }
}

If you use REST API, you can extend the controller

'use strict';

/**
 *  article controller
 */

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

module.exports = createCoreController('api::article.article', ({ strapi }) => ({
  async find(ctx) {
    // Calling the default core action
    const { data, meta } = await super.find(ctx);

    const query = strapi.db.query('api::article.article');

    await Promise.all(
      data.map(async (item, index) => {
        const article = await query.findOne({
          where: {
            id: item.id,
          },
          populate: ['createdBy'],
        });
        
        data[index].attributes.createdBy = {
          id: page.createdBy.id,
          firstname: page.createdBy.firstname,
          lastname: page.createdBy.lastname,
        };
      })
    );

    return { data, meta };
  },
}));

@strapi-bot
Copy link

This issue has been mentioned on Strapi Community Forum. There might be relevant details there:

https://forum.strapi.io/t/cant-get-createdby-from-api/15687/2

@derrickmehaffy
Copy link
Member

This is correct, we don't populate anything by default so you need to specify the population in v4

@vandrieu
Copy link
Author

@derrickmehaffy the last version of the docs reads:

populateCreatorFields
Boolean
Toggles including the created_by and updated_by fields in the API response.

English is not my main language so maybe I just don't understand the sentence correctly. To me, it means if populateCreatorFields is true, then the created_by and updated_by fields will be included in the API response.

Did I misunderstood? If I misunderstood, then would you please clarify what is the real meaning of populateCreatorFields?

Also, if populateCreatorFields does not allow to include created_by and updated_by in the API response then what is the 'official' way of doing it (besides using fancy workarounds like the ones above)?

@derrickmehaffy
Copy link
Member

@derrickmehaffy the last version of the docs reads:

populateCreatorFields
Boolean
Toggles including the created_by and updated_by fields in the API response.

English is not my main language so maybe I just don't understand the sentence correctly. To me, it means if populateCreatorFields is true, then the created_by and updated_by fields will be included in the API response.

Did I misunderstood? If I misunderstood, then would you please clarify what is the real meaning of populateCreatorFields?

Also, if populateCreatorFields does not allow to include created_by and updated_by in the API response then what is the 'official' way of doing it (besides using fancy workarounds like the ones above)?

This is a legacy setting from Strapi v3 which automatically populated those fields, in v4 this is no longer an option so this setting I believe now only allows you to populate them at query time.

We have no method to auto populate anything in Strapi v4, so this documentation probably could be updated to reflect that.

@jsanta
Copy link

jsanta commented Nov 7, 2022

I know this issue is closed but, is the creator fields issue solved in version 4.* ? I'm trying it using the REST API and those fields are not appearing on the response.

@arkni8
Copy link

arkni8 commented Feb 12, 2023

Hello maintainers and @derrickmehaffy of this documentation. I see that this issue is still confusing some people who are coming in new to Strapi (as was I) so after I figured it out, I thought I should just help you guys update the documentation a bit to reflect the steps better for v4.

So I have made the necessary changes in my local environment but I am not completely sure how to proceed with the push request after that (this is my first time doing a contribution :) )

https://github.com/arkni8/documentation/blob/dev/populating-field/docs/developer-docs/latest/developer-resources/database-apis-reference/rest/populating-fields.md

That's the link to the fork I have worked on, you guys can check the changes I have made in the commit. And then maybe instruct me what to do next..

@derrickmehaffy
Copy link
Member

Hello maintainers and @derrickmehaffy of this documentation. I see that this issue is still confusing some people who are coming in new to Strapi (as was I) so after I figured it out, I thought I should just help you guys update the documentation a bit to reflect the steps better for v4.

So I have made the necessary changes in my local environment but I am not completely sure how to proceed with the push request after that (this is my first time doing a contribution :) )

https://github.com/arkni8/documentation/blob/dev/populating-field/docs/developer-docs/latest/developer-resources/database-apis-reference/rest/populating-fields.md

That's the link to the fork I have worked on, you guys can check the changes I have made in the commit. And then maybe instruct me what to do next..

Can you open a PR against the documentation repo 🙏

@ciekawy
Copy link

ciekawy commented Jun 29, 2023

This is correct, we don't populate anything by default so you need to specify the population in v4

how what and where I can specify to get the createdBy in graphql? I was unable to find anything in the documentation.

@ciekawy
Copy link

ciekawy commented Jun 30, 2023

wow and I just found the createdBy isn't even regular user who signed up e.g. via google, thats sooo confusing ;(

@kristijorgji
Copy link

I created a Post content type and want to return the author back when I fetch the posts, how can I do this?

I do see in Strapi admin panel on the right side "author: Somename" but even with query parameter populate=* I still don't receive author and createdAt fields

@kristijorgji
Copy link

Extending the controller works and returns createdBy also in latest Strapi version "@strapi/strapi": "4.11.3", but it is not a good solution!

WHY?
Because you query n+1 times, you fetch

  1. all posts
  2. for every post, you fetch again and populate the createdBy field

it has a performance impact so it is not the proper solution.

Proper solution would be to tell await super.find somehow to populate this field while fetching all the records + handling the pagination

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
issue: bug Issue reporting a bug severity: medium If it breaks the basic use of the product but can be worked around source: core:strapi Source is core/strapi package status: pending reproduction Waiting for free time to reproduce the issue, or more information
Projects
None yet
Development

No branches or pull requests

9 participants