Strapi v4 too much nested data
Asked Answered
L

7

8

I'm rewriting strapi v3 queries to v4 (GraphQL), and with new fields 'data' and 'attributes', I have a problem going too much deep into nested objects, an example of how data looks:

user {
  data {
    id
    attributes {
      company {
        data {
          id
          attributes {
            location {
              data {
                id
                ...
              }
          }
      }
    
    }
  }
}

Am I missing something in the documentation, is there a way to avoid this much nesting, should I restructure data in Model, or?

Ledger answered 10/2, 2022 at 11:17 Comment(0)
G
2

This is a known pain point for many, but no immediate official solution in sight. Gotta deal with it.

https://forum.strapi.io/t/discussion-regarding-the-complex-response-structure-for-rest-graphql-developer-experience/13400/35

Grefer answered 28/2, 2022 at 7:48 Comment(2)
Anyone have a good work around?Pitts
So far my best solution is to just try to break up stuff in many components and flatten the data when its passed into the component. Ex. ``` {records.data.map(({ id, attributes }) => ( <Record key={id} {...{ ...attributes, id }} /> ))} ```Pitts
P
1

My friend, that's the way now:

user.data.attributes.company.data.attributes.location.data 
Prinz answered 17/4, 2022 at 1:52 Comment(0)
C
0

For solve this you can install the strapi-plugin-transformer

And pass the needed configurations to remove data and attributes from the response.

Cuthbertson answered 20/2, 2023 at 3:30 Comment(2)
I think this is just for API requests not GraphQL?Denouement
There's no way to do from the Strapi server with graphql, but there are solutions, you can use the following package, it will be able to remove the Strapi wrappers: github.com/Dave136/smapperCuthbertson
S
0

You can simplify the deeply nested structures in your Strapi v4 GraphQL queries using the strapi-flatten-graphql library (I am the author). This lightweight TypeScript library provides functions to flatten the nested GraphQL responses, making them more concise and easier to work with.

To get started, install the library using npm:

npm install strapi-flatten-graphql

Import the necessary functions from the library:

import { flattenEntityResponse } from 'strapi-flatten-graphql';

Then, use the flattenEntityResponse function to flatten your GraphQL responses:

const response = /* Your GraphQL response object */;
const flattenedResponse = flattenEntityResponse(response);

// Use the flattened response in your application
console.log(flattenedResponse);

The flattenEntityResponse function handles the transformation of the nested structure into a simpler, flattened format. It also includes TypeScript typings to ensure type safety while working with the flattened data.

By using strapi-flatten-graphql, you can streamline your Strapi v4 GraphQL queries and improve the readability and maintainability of the code.

Sacrum answered 7/7, 2023 at 15:29 Comment(0)
G
0

There is a new package to resolve this issue strapi-flatten-graphql

This will eliminate the data and attributes

Please check the package documentation for more details

Gillam answered 1/8, 2023 at 9:15 Comment(0)
B
0

Try to use graphql

git clone https://github.com/GavinXue/strapi-study-cases.git

copy folder graphql from plugin on your project inside plugin also extension/graphql and set configuracion on config/plugins also on index

enter image description here

Bestialize answered 13/8, 2023 at 23:48 Comment(0)
H
0

It's kind of annoying, but you can deal with it in Typescript. Below is my interfaces.tsx file. It has more information than needed, but it works well. The idea is to define a generic interface with a data field which will contain an object with an id and attributes and be able to use it for any Generic type T:

// ---------------------- Custom interfaces and types ----------------------

export interface StateObject<T>  extends Type<T> {
    temp: StrapiObject<T>;
}

export interface Type<T> {
    data: StrapiObject<T>;
}

export interface TypeArray<T> {
    data: StrapiObject<T>[];
}

export interface StrapiObject<T> {
    id: number,
    attributes: T
}

interface Image {
    url: string;
}

type ImageField = Type<Image>;

export interface DivisionAttributes {
    name: string;
    createdAt: string;
    updatedAt: string;
    publishedAt: string;
    locale: string;
    categories: Category | CategoryArray;
    medical_products: MedicalProduct | MedicalProductArray;
    photo?: ImageField; // Adjusted to match the Type structure
    localizations: Type<any>; // Assuming localizations can be of any structure
}

export interface CategoryAttributes {
    name: string;
    description: string;
    divisions: Division | DivisionArray;
    medical_products: MedicalProduct | MedicalProductArray;
    image: ImageField; // Adjusted to match the Type structure
}

interface MedicalProductAttributes {
    name: string;
    description: string;
    price: number;
    photo: ImageField; // Adjusted for consistency
    localizations: Type<any>; // Adjusted to match the Type structure
}


export type AnimationStage = 'idle' | 'fadingIn' | 'fadingOut' | 'error';

// ~ Hack to get the response type of the Strapi API right 
export type DivisionArray = TypeArray<DivisionAttributes>;
export type CategoryArray = TypeArray<CategoryAttributes>;
export type MedicalProductArray = TypeArray<MedicalProductAttributes>;

export type Division = Type<DivisionAttributes>;
export type Category = Type<CategoryAttributes>;
export type MedicalProduct = Type<MedicalProductAttributes>;


Heparin answered 28/2, 2024 at 14:12 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.