strapi-plugin-comments icon indicating copy to clipboard operation
strapi-plugin-comments copied to clipboard

Proper way to update author info

Open jnovak-SM2Dev opened this issue 1 year ago • 14 comments

I'm a bit confused about how the author is handled. I have to pass in the author's email, avatar, etc. What happens if that info changes (ie the user updates their profile)? Do I need to get all comments by the user and update each instance?

jnovak-SM2Dev avatar May 19 '23 14:05 jnovak-SM2Dev

Looks like this was somewhat answered here, but how can I add additional fields/extend calls for this plugin for GraphQL?

jnovak-SM2Dev avatar May 19 '23 14:05 jnovak-SM2Dev

If you base on Strapi Users simply add fields to them and populate proper ones in your query.

For more detailed suggestion please provide idea you've got.

cyp3rius avatar May 19 '23 14:05 cyp3rius

I guess the larger question would be, what is the proper way to use extensionService with this plugin? I'm not sure how to override the findAllFlat and findAllInHierarchy GraphQL methods to be able to adjust what is returned.

jnovak-SM2Dev avatar May 19 '23 14:05 jnovak-SM2Dev

About extensions you can read here but I guess you want to add more fields to User Collection to which we have got relation in the comment schema. After adding fields you should follow the "Populating" chapter in the Strapi Doc.

cyp3rius avatar May 19 '23 14:05 cyp3rius

@cyp3rius I understand how to add fields to users and how to populate. My confusion is around extending GraphQL for comments specifically. For example, this is what i'd expect to be able to do, something like below.

 extensionService.use(({ strapi }) => ({
  typeDefs: `
    type CommentSingle {
      authorFull: UsersPermissionsUserEntityResponse
    }
  `,
  resolvers: {
    Query: {
      findAllFlat: {
        resolve: async (parent, args, context) => {
          const { toEntityCollectionResponse } = strapi.service(
            "plugin::graphql.format"
          ).returnTypes;

          const data = await strapi.services["api::comment.comment"].find(
            {}
          );

          const response = toEntityCollectionResponse(data.results);
          return response;
        },
      },
    },
  },
}));

Is there an example on how to do this or does this need to be handled a special way? Sorry, it's very confusing and Strapi 4's docs kind of suck.

jnovak-SM2Dev avatar May 19 '23 15:05 jnovak-SM2Dev

Let me check that on weekend and back to you with some advice :)

cyp3rius avatar May 19 '23 16:05 cyp3rius

@cyp3rius Thanks! That'd be great. Even you just find a sample somewhere or an article. It's just tough cause Strapi's docs are all over the place with V3 and V4, GraphQL makes it tough, and then you add in the complexity of this plugin having specific calls and types, it's tough to know how to handle things properly.

jnovak-SM2Dev avatar May 19 '23 16:05 jnovak-SM2Dev

@SM2DevLLC I did some research and coding. What you expect you should be able to do not as a plugin extension but as part of the register routing of your Strapi project.

File: src/index.js

'use strict';

module.exports = {
  /**
   * An asynchronous register function that runs before
   * your application is initialized.
   *
   * This gives you an opportunity to extend code.
   */
  register({ strapi }) {
    const extensionService = strapi.service("plugin::graphql.extension");
    
    extensionService.use(({ strapi }) => ({
      typeDefs: `
        type CommentSingle {
          authorFull: UsersPermissionsUserEntityResponse
        }
      `,
      resolvers: {
        Query: {
          findAllFlat: {
            resolve: async (parent, args, context) => {
              const { toEntityCollectionResponse } = strapi.service(
                "plugin::graphql.format"
              ).returnTypes;
    
              const data = await strapi.services["api::comment.comment"].find(
                {}
              );
    
              const response = toEntityCollectionResponse(data.results);
              return response;
            },
          },
        },
      },
    }));
  },

  /**
   * An asynchronous bootstrap function that runs before
   * your application gets started.
   *
   * This gives you an opportunity to set up your data model,
   * run jobs, or perform some special logic.
   */
  bootstrap(/*{ strapi }*/) { },
};
Screenshot 2023-05-20 at 00 02 02

Is that what you expect to do?

cyp3rius avatar May 19 '23 22:05 cyp3rius

@cyp3rius Yes that's what i'm already doing. That's where the code is. It just doesn't work. I think part of it is the ["api::comment.comment"] portion. I think it may need to be ["plugin::comment.comment"] or something along those lines.

jnovak-SM2Dev avatar May 19 '23 22:05 jnovak-SM2Dev

Please add the like feature, manage likes for each comment. I think adding the like feature will make your plugin more perfect

kienbui195 avatar May 29 '23 07:05 kienbui195

@cyp3rius It looks like the authorUser relationship exists, it just isn't being allowed to be selected in GraphQL queries. Can you please enable this? If you do, it'll be easy for people to select that as a return field and even extend it.

jnovak-SM2Dev avatar Jul 03 '23 19:07 jnovak-SM2Dev

Looking into that

cyp3rius avatar Jul 05 '23 19:07 cyp3rius

Hi @jnovak-SM2Dev,

I dug a bit deeper. Comment entity connects either to Strapi user or displays details provided at comment creation. Both are displayed as author. If comment is created by strapi user then details of an user are displayed. If relation to user does not exist plugin falls back to reading author details save at comment level.

Long story short you cannot read author as a strapi user or author as static values at comments level. Only one of them at the time. You query both from the same field.

CodeVoyager avatar Mar 16 '24 09:03 CodeVoyager

you just need to extend the response, create a field and resolve, in index.js

const extensionService = strapi.plugin("graphql").service("extension");
    extensionService.use(({ nexus }) => ({
      types: [
        nexus.extendType({
          type: "CommentSingle",
          definition(t) {
            t.string("authorFull", {
              type: "UsersPermissionsUserEntityResponse",
              description: "Author full data",
              resolve: async (parent, root, args) => {
                const { toEntityResponse } = strapi.service(
                  "plugin::graphql.format"
                ).returnTypes;
                console.log("parent", parent.author.id);
                const user = await strapi.db
                  .query("plugin::users-permissions.user")
                  .findOne({
                    where: { id: parent.author.id },
                    populate: { profile_image: true },
                  });
                console.log("user", user);

                return toEntityResponse(user);
              },
            });
          },
        }),
      ],

jusiho avatar Jun 20 '24 13:06 jusiho