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

Get users/me error in deepPopulate #15

Open
nnnext opened this issue Oct 27, 2024 · 1 comment
Open

Get users/me error in deepPopulate #15

nnnext opened this issue Oct 27, 2024 · 1 comment
Assignees

Comments

@nnnext
Copy link

nnnext commented Oct 27, 2024

Fresh installation of strapi Launchpad ending in an error when trying to get User Data after register and login.

Normal Strapi Installation works without problems.

We used Thunder Client

  1. Post request to create a user
  2. Post request to login the user with his credentials
  3. Get request on /api/users/me ending in the 500 InternalServerError

Logfile

error: Cannot read properties of undefined (reading 'attributes')
TypeError: Cannot read properties of undefined (reading 'attributes')
at getDeepPopulate (...\strapi\dist\src\middlewares\deepPopulate.js:15:45)
at ...\strapi\dist\src\middlewares\deepPopulate.js:68:34
at dispatch (...\strapi\node_modules\koa-compose\index.js:42:32)
at dummyMiddleware (...\strapi\node_modules@strapi\core\dist\services\server\middleware.js:25:38)
at dispatch (...\strapi\node_modules\koa-compose\index.js:42:32)
at ...\strapi\node_modules\koa-favicon\index.js:42:14
at dispatch ...\strapi\node_modules\koa-compose\index.js:42:32)
at dummyMiddleware (...\strapi\node_modules@strapi\core\dist\services\server\middleware.js:25:38)
at dispatch (...\strapi\node_modules\koa-compose\index.js:42:32)
at ...\strapi\node_modules@strapi\core\dist\middlewares\body.js:45:15

... is the project folder.

@nnnext
Copy link
Author

nnnext commented Oct 27, 2024

we updated the deepPopulate.ts file in the Strapi > src > middlewares folder and now the user can login and gets userdata. hope this will help others.

/**

  • deepPopulate middleware
    */

import type { Core } from '@strapi/strapi';
import { UID } from '@strapi/types';
import { contentTypes } from '@strapi/utils';
import pluralize from 'pluralize';

interface Options {
/**

  • Fields to select when populating relations
    */
    relationalFields?: string[];
    }

const { CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE } = contentTypes.constants;

const extractPathSegment = (url: string) => url.match(//([^/?]+)(?:?|$)/)?.[1] || '';

const getModelUID = (path: string): UID.Schema => {
// Special handling for users-permissions routes
if (path === 'users' || path === 'me') {
return 'plugin::users-permissions.user';
}

// Logic for regular content types
const singular = pluralize.singular(path);
return api::${singular}.${singular} as UID.Schema;
};

const getDeepPopulate = (uid: UID.Schema, opts: Options = {}) => {
const model = strapi.getModel(uid);

// Add safety check
if (!model || !model.attributes) {
console.warn(Model not found for UID: ${uid});
return {};
}

const attributes = Object.entries(model.attributes);

return attributes.reduce((acc: any, [attributeName, attribute]) => {
switch (attribute.type) {
case 'relation': {
const isMorphRelation = attribute.relation.toLowerCase().startsWith('morph');
if (isMorphRelation) {
break;
}

    // Ignore not visible fields other than createdBy and updatedBy
    const isVisible = contentTypes.isVisibleAttribute(model, attributeName);
    const isCreatorField = [CREATED_BY_ATTRIBUTE, UPDATED_BY_ATTRIBUTE].includes(attributeName);

    if (isVisible) {
      if (attributeName === 'testimonials') {
        acc[attributeName] = { populate: "user.image" };
      } else {
        acc[attributeName] = { populate: "*" };
      }
    }

    break;
  }

  case 'media': {
    acc[attributeName] = { populate: "*" };
    break;
  }

  case 'component': {
    const populate = getDeepPopulate(attribute.component, opts);
    acc[attributeName] = { populate };
    break;
  }

  case 'dynamiczone': {
    // Use fragments to populate the dynamic zone components
    const populatedComponents = (attribute.components || []).reduce(
      (acc: any, componentUID: UID.Component) => {
        acc[componentUID] = { populate: getDeepPopulate(componentUID, opts) };

        return acc;
      },
      {}
    );

    acc[attributeName] = { on: populatedComponents };
    break;
  }
  default:
    break;
}

return acc;

}, {});
};

export default (config, { strapi }: { strapi: Core.Strapi }) => {
return async (ctx, next) => {
if (ctx.request.url.startsWith('/api/') && ctx.request.method === 'GET' && !ctx.query.populate) {
strapi.log.info('Using custom Dynamic-Zone population Middleware...');

  const pathSegment = extractPathSegment(ctx.request.url);
  const uid = getModelUID(pathSegment);

  // @ts-ignores 
  try {
    ctx.query.populate = getDeepPopulate(uid);
  } catch (error) {
    console.error(`Error in deepPopulate middleware for path ${pathSegment}:`, error);
    // Continue without population if there's an error
  }
}
await next();

};
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants