How to iterate through the Dynamic Zone results in a custom resolver?

System Information
  • Strapi Version: 4.2.3
  • Operating System: Windows 10
  • Database: SQL Lite
  • Node Version: 16.15.1
  • NPM Version: 8.11.0
  • Yarn Version:

Question
How do I iterate through the query result and replace all the “value” fields with the external data fetched in an external API?

Background
I am a newbie to Strapi and have been using it for about a month. I am working on a proof of concept that the data from an external API can dynamically replace values within the static content residing in the Strapi CMS. So far, I can fetch the external data and query the static content successfully. However, I do not know how to iterate through the result and perform a search and replace.

Below is my GrapQL query for getting the static content.

query truthLendingDisclosures {
  truthLendingDisclosures {
    data {
      id
      attributes {
        title
        body {
          __typename
          ... on ComponentPagesDynamicSection {
            section {
              id
              title
              text
              value
              __typename
            }
          }
          ... on ComponentPagesStaticSection {
            section {
              id
              title
              text
              __typename
            }
          }
        }
      }
    }
  }
}

Query results

{
    "data": {
        "truthLendingDisclosures": {
            "data": [
                {
                    "id": "1",
                    "attributes": {
                        "title": "Truth in Lending Disclosure",
                        "body": [
                            {
                                "__typename": "ComponentPagesDynamicSection",
                                "section": [
                                    {
                                        "id": "1",
                                        "title": null,
                                        "text": "Account #",
                                        "value": "{1-123456-1}",
                                        "__typename": "ComponentSharedDynamicContent"
                                    },
                                    {
                                        "id": "2",
                                        "title": null,
                                        "text": "Finance Charge Start Date",
                                        "value": "{07/21/2022}",
                                        "__typename": "ComponentSharedDynamicContent"
                                    },
                                    {
                                        "id": "3",
                                        "title": null,
                                        "text": "Amount of Pays [X] through [Y]",
                                        "value": "{$###.##}",
                                        "__typename": "ComponentSharedDynamicContent"
                                    },
                                    {
                                        "id": "4",
                                        "title": null,
                                        "text": "Amount of Payments [Z]",
                                        "value": "$###.##",
                                        "__typename": "ComponentSharedDynamicContent"
                                    },
                                    {
                                        "id": "5",
                                        "title": null,
                                        "text": "Due [Frequency] Starting",
                                        "value": "{07/21/2022}",
                                        "__typename": "ComponentSharedDynamicContent"
                                    },
                                    {
                                        "id": "6",
                                        "title": "Annual Percentage Rate",
                                        "text": "The cost of your credit as a yearly rate.",
                                        "value": "{###.##% APR}",
                                        "__typename": "ComponentSharedDynamicContent"
                                    },
                                    {
                                        "id": "7",
                                        "title": "Finance Charge",
                                        "text": "The dollar amount the credit cost you.",
                                        "value": "{$#,###.##}",
                                        "__typename": "ComponentSharedDynamicContent"
                                    },
                                    {
                                        "id": "8",
                                        "title": "Amount Financed",
                                        "text": "The amount of credit provided to you on your behalf.",
                                        "value": "{$#,###.##}",
                                        "__typename": "ComponentSharedDynamicContent"
                                    },
                                    {
                                        "id": "9",
                                        "title": "Total of Payments",
                                        "text": "The amount you will have paid after you have made all payments as scheduled.",
                                        "value": "{$#,###.##}",
                                        "__typename": "ComponentSharedDynamicContent"
                                    },
                                    {
                                        "id": "10",
                                        "title": "Total Sale Price",
                                        "text": "The total cost of your purchase on credit, including your down payment of [$###.##].",
                                        "value": "{$#,###.##}",
                                        "__typename": "ComponentSharedDynamicContent"
                                    }
                                ]
                            },
                            {
                                "__typename": "ComponentPagesStaticSection",
                                "section": [
                                    {
                                        "id": "1",
                                        "title": "Security Interest",
                                        "text": "You are giving a security interest in the Goods you are purchasing, the below Electronic Missed Payment Authorization, RCP Authorization, and Payment Authorization (if applicable). The Electronic Missed Payment Authorization, RCP Authorization, and Payment Authorization (if applicable) securing other agreements with us may also secure this Agreement.",
                                        "__typename": "ComponentSharedStaticContent"
                                    },
                                    {
                                        "id": "2",
                                        "title": "Late Charge",
                                        "text": "[If you fail to pay any payment in full within # days after it is due, you may be charged a late fee equal to #% of the payment due or $##, whichever is more.]",
                                        "__typename": "ComponentSharedStaticContent"
                                    },
                                    {
                                        "id": "3",
                                        "title": "Prepayment",
                                        "text": "See the Loan Agreement below for information about nonpayment, default, any required repayment in full before the scheduled date, and prepayment refunds and penalties. ",
                                        "__typename": "ComponentSharedStaticContent"
                                    }
                                ]
                            }
                        ]
                    }
                }
            ]
        }
    }
}

Custom Resolver

const axios = require("axios");
const EXTERNAL_API_URL = "http://jsonplaceholder.typicode.com/users";

exports.Query = {
  
  truthLendingDisclosures: async () => {
    // set the format for the static content
    const { toEntityResponseCollection } = strapi
      .plugin("graphql")
      .service("format").returnTypes;

    // calling external Java API
    // externalData will contain all the dynamic values for the static content
    const externalData = await axios.get(EXTERNAL_API_URL);
    console.log(externalData);

    // query static content from Strapi CMS
    const staticContent = await strapi.entityService.findMany(
      "api::truth-lending-disclosure.truth-lending-disclosure"
    );

    // Not sure how to do this yet

    /*
     * we can perform data substitution by iterating through
     * the static content and replace the values with the
     * external data
     */

    // for the GraphQL IDE
    return toEntityResponseCollection(staticContent);
  },
};

Iterating through the results of your GraphQL query and replacing the “value” fields with data fetched from an external API can be achieved by looping through the nested structure of your query result and performing the replacements accordingly. Here’s how you can do it:
exports.Query = {
truthLendingDisclosures: async () => {
// Fetching external data from the API
const externalData = await axios.get(EXTERNAL_API_URL);

// Querying static content from Strapi CMS
const staticContent = await strapi.entityService.findMany(
  "api::truth-lending-disclosure.truth-lending-disclosure"
);

// Iterate through the static content
const updatedStaticContent = staticContent.map(item => {
  // Check if the item has a "body" attribute
  if (item.attributes && item.attributes.body) {
    // Iterate through the "body" array
    item.attributes.body.forEach(section => {
      // Check if the section has a "value" field
      if (section.value) {
        // Replace the "value" with data from the external API
        // Here, you can replace the "value" with corresponding data from the external API based on your logic
        // For example, if the "value" corresponds to a specific field in the external data, you can replace it accordingly
        section.value = externalData.someField; // Replace with actual field from external data
      }
    });
  }
  return item;
});

// Return the updated static content
return toEntityResponseCollection(updatedStaticContent);

},
};
In this code:

  • We fetch external data using axios.
  • We iterate through the static content retrieved from Strapi CMS.
  • For each item in the static content, we iterate through its “body” array.
  • If a “value” field exists in a section of the body, we replace it with data fetched from the external API.
  • Finally, we return the updated static content.

Adjust the replacement logic according to your requirements and the structure of the external data fetched from the API.

Hope this helps you with your Bank Statement Loan integration! Let me know if you have further questions.