module.exports = {
parseXML: function(file_path, callback) {
callback("test 1")
readFile(file_path.toString(), "utf-8", function(err, data) {
if (err) callback(err);
parseString(data, function(err, result) {
if (err) callback(err);
callback("test 2")
var json = result;
delete json.sitemapindex.sitemap[1].lastmod;
var builder = new xml2js.Builder();
var xml = builder.buildObject(json);
write2File(file_path.toString(), xml, function(err, data) {
if (err) callback(err);
callback("test 3")
callback("successfully written our update xml to ",file_path.toString());
});
});
});
callback("test 4")
}
}
This is a function to parse XML to JSON and modify the JSON and write back to XML. I called this function in gatsby-node.js
in onPostBuild
like this
exports.onPostBuild = async () => {sitemap_mod.parseXML("filename")}
However, in the gatsby build
, it only printed out test:1
and test:4
, which means it failed to execute anything in the readFile function. I suppose this is because the onPostBuild
is an async function and I need to add some await
state in my code. I applied this function in other node API such as onPostBootstrap
and onCreateDevServer
and they were both working properly, able to execute readFile
and write2File
function. So I think there's something wrong about my usage of onPostBuild
. Thanks for your help!
Yes, you should indeed make sure to wait for the function to finish.
You need to wait for the three asynchronous calls you have inside parseXML
. I usually use promisify
to turn them into async functions:
const { promisify } = require("util");
const asyncParseString = promisify(parseString);
const asyncReadFile = promisify(readFile);
const asyncWrite2File = promisify(write2File);
function transformJsonToXml(json) {
...
}
async function parseXML(file_path) {
const data = await asyncReadFile(file_path.toString(), "utf-8");
const json = await asyncParseString(data);
await asyncWrite2File(file_path.toString(), transformJsonToXml(json));
}
Your onPostBuild
then needs to wait for parseXML
to finish. So either put an await
before the parseXML
call or just use
exports.onPostBuild = () => sitemap_mod.parseXML("filename")