Search code examples
next.jsstrapi

With Strapi 4 how can I get each users music events


I'm using strapi 4 with nextjs.

In the app strapi holds music events for each user and each user should be able add and retrieve there own music events.

I am having trouble retrieving each users music events from strapi 4

I have a custom route and custom controller

The custom route is in a file called custom-event.js and works ok it is as follows:

module.exports = {
  routes: [
    {
      method: 'GET',
      path: '/events/me',
      handler: 'custom-controller.me',
      config: {
        me: {
          auth: true,
          policies: [],
          middlewares: [],
        }
      }
    },
  ],
}

The controller id a file called custom-controller.js and is as follows:

module.exports = createCoreController(modelUid, ({strapi }) => ({
  async me(ctx) {
    try {
      const user = ctx.state.user;

      if (!user) {
        return ctx.badRequest(null, [
          {messages: [{ id: 'No authorization header was found'}]}
        ])
      }

      // The line below works ok
      console.log('user', user);

      // The problem seems to be the line below
      const data = await strapi.services.events.find({ user: user.id})
      
      // This line does not show at all 
      console.log('data', data);

      if (!data) {
        return ctx.notFound()
      }

      return sanitizeEntity(data, { model: strapi.models.events })
    } catch(err) {
      ctx.body = err
    }
  }
}))

Note there are two console.logs the first console.log works it outputs the user info The second console.log outputs the data it does not show at all. The result I get back using insomnia is a 200 status and an empty object {}

The following line in the custom-controller.js seems to be where the problem lies it works for strapi 3 but does not seem to work for strapi 4

const data = await strapi.services.events.find({ user: user.id})

Solution

  • After struggling for long time, days infact, I eventually got it working. Below is the code I came up with. I found I needed two queries to the database, because I could not get the events to populate the images with one query. So I got the event ids and then used the event ids in a events query to get the events and images.

    Heres the code below:

    const utils = require('@strapi/utils')
    const { sanitize } = utils
    
    const { createCoreController } = require("@strapi/strapi").factories;
    const modelUid = "api::event.event"
    
    module.exports = createCoreController(modelUid, ({strapi }) => ({
      async me(ctx) {
      try {
      const user = ctx.state.user;
    
      if (!user) {
        return ctx.badRequest(null, [
          {messages: [{ id: 'No authorization header was found'}]}
        ])
      }
    
         // Get event ids 
      const events = await strapi
        .db
        .query('plugin::users-permissions.user')
        .findMany({
            where: {
              id: user.id
            },
            populate: { 
              events: { select: 'id'}
            }
          })
    
     
    
          if (!events) {
            return ctx.notFound()
          }
    
          // Get the events into a format for the query
          const newEvents = events[0].events.map(evt => ({ id: { $eq: evt.id}}))
    
          // use the newly formatted newEvents in a query to get the users
          // events and images
          const eventsAndMedia = await strapi.db.query(modelUid).findMany({
            where: {
              $or: newEvents
            },
            populate: {image: true}
          })
    
    
         return sanitize.contentAPI.output(eventsAndMedia, 
                         strapi.getModel(modelUid))
        } catch(err) {
          return ctx.internalServerError(err.message)
        }
      }
    }))