Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strapi CMS: Fetch Nested Content

Tags:

strapi

I am using Strapi CMS and struggling with fetching the nested/deep content’s data. E.g.: Let’s say, I have below content types created and relations are defined.

Person: Name, Age

Address: City, Country

Contact: Code, Number

Person has one Address

Address has many Contacts

Now the problem is, when I access ‘/persons’, I get only Name, Age and Address object. But address object does not have the contact information associated with the address.

Can somebody help me to get this resolved or point me towards any such article?

like image 656
ivp Avatar asked Nov 28 '19 09:11

ivp


3 Answers

Firstly you'll need a custom controller function for this. In /api/person/controllers/Person.js you can export your custom find function. There you can define which fields you want to populate:

module.exports = {
  find: ctx => {
    return strapi.query('person').find(ctx.query, ['address', 'contact']);
  },
};

Another solution works for me as well:

module.exports = {
  find: ctx => {
    return strapi.query('person').find(ctx.query, [
       { path: 'address' },
       { path: 'contact' },
    ]);
  },
};

Edited example with one level deeper populate:

module.exports = {
  find: ctx => {
    return strapi.query('person').find(ctx.query, [
      {
        path: 'address',
        populate: {
          path: 'contacts',
        },
      },
    ]);
  },
};

For reference see the most recent beta docs:

https://strapi.io/documentation/3.0.0-beta.x/concepts/queries.html#api-reference

like image 73
Roland Balogh Avatar answered Nov 12 '22 08:11

Roland Balogh


I was able to get some nested data using the following:

api/booking/controllers/booking.js:

async find(ctx) {
    const entities = await strapi.services.booking.find(ctx.query, [
        'class',
        'class.capacity',
        'class.date',
        'class.category',
        'class.category.name',
        'class.type',
        'class.type.name',
        'class.startTime',
        'class.endTime',
      ]);
    }

    return entities.map((entity) =>
      sanitizeEntity(entity, { model: strapi.models.booking }),
    );
  },

where my booking has a relation to class and user. So, by default it just comes back with the class id's - but I'd like to be able to see fields from the class relation all in the same payload.

ie, instead of this:

user: "123eqwey12ybdsb233",
class: "743egwem67ybdsb311"

I'm trying to get:

user: {
  id: "123eqwey12ybdsb233",
  email: "[email protected]",
  ...
},
class: {
  id: "743egwem67ybdsb311",
  capacity: 10,
  type: {
    name: "Individual",
    description: "..."
    ...
  }
  ...
}

Now, the above works for non-relational fields.. but for fields that are a relation of a relation (ie. class.category and class.type), it doesn't seem to work as I would've expected.

In my database, the relation chain is like so: booking -> class -> category / type, where category and type each have a name and some other fields.

like image 32
Mykhaylo Avatar answered Nov 12 '22 08:11

Mykhaylo


Only this worked for me

const data = await strapi
  .query("grand_collection")
  .model.find({ user: id })
  .populate({ path: "parent_collection", populate: { path: "child_collection" } });
like image 1
Moiz Sohail Avatar answered Nov 12 '22 08:11

Moiz Sohail