Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to asynchronously manipulate a deeply nested object by referennce

I am working on a gridsome project, where I am manipulating a schema and rendering pages based on that. So, I am passing a reference of schema to a function, which function will manipulate a deeply nested object like,

{
URL: "some.url"
paramas: {"some params}
}

to

{
URL: "some.url"
params: {"some params}
props:{
        data:[] || {}
    }
}

this manipulation will happen based on the URL and param, so I need to use forEach loop but unfortunately, forEach loop is not asynchronous.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Here I am out of ideas what I need to do if I want to manipulate all those objects (more than 100) from other module and it has to be asynchronous.

a demo schema:

{
      "name": "home",
      "path": "/",
      "header": "top_header",
      "footer": "bottom_footer",
      "rows": [
        {
          "row_class": "bg-white",
          "columns_class": "cols-66-33 cols-separated cols--height-equal",
          "column_1": [
            {
              "name": "Coral/HomeNews",
              "props": {
                "tag": "main"
              }
            }
          ],
         }
    ]
}

edit:
So I am calling a function from other module like

await dataExtender(_schema);

which contains a function(currently I am developing it, and not complete) which is

const dataExtender = async _schema => {
  // Define forEach function

  console.log(chalk.green("Data Extending starts from module level"));

  

  await Promise.all(
    _schema.pages.forEach(async page => {
      page.rows.forEach(row => {
        row.column_1.forEach(async column => {
          if (column.url !== undefined) {
            await axios
              .post(column.url, column.param || {})
              .then(data => {
                console.log(chalk.green("Extending"));
                if (Array.isArray(data.data)) {
                  column.props.data = [...data.data];
                } else {
                  column.props.data = { ...data.data };
                }
              })
              .catch(err => {
                console.log(err);
              });
          }
        });
        if (row.column_2 !== undefined) {
          row.column_2.forEach(async column => {
            if (column.url !== undefined) {
              await axios
                .post(column.url, column.param || {})
                .then(data => {
                  column.props.data = data.data;
                })
                .catch(err => {
                  console.log(err);
                });
            }
          });
        }
      });
    }),
  );

  console.log(chalk.green("Data Extending finishes from module level"));
  return _schema;
};

>Solution :

While forEach itself is not async-aware, that doesn’t stop you from being able to push the asynchronous modification promises onto a list and awaiting for all of them at the end.

import axios from "axios";

async function processColumn(column) {
  const data = await axios.post(column.url, column.param || {});
  console.log(chalk.green("Extending"));
  if (Array.isArray(data.data)) {
    column.props.data = [...data.data];
  } else {
    column.props.data = { ...data.data };
  }
}

async function processColumn2(column) {
  const data = await axios.post(column.url, column.param || {});
  column.props.data = data.data;
}

const dataExtender = async (_schema) => {
  console.log(chalk.green("Data Extending starts from module level"));
  const promises = [];

  _schema.pages.forEach((page) => {
    page.rows.forEach((row) => {
      row.column_1.forEach((column) => {
        if (column.url !== undefined) {
          promises.push(processColumn(column));
        }
      });
      if (row.column_2 !== undefined) {
        row.column_2.forEach((column) => {
          if (column.url !== undefined) {
            promises.push(processColumn2(column));
          }
        });
      }
    });
  });
  await Promise.all(promises);
  console.log(chalk.green("Data Extending finishes from module level"));
  return _schema;
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading