Reputation: 6698
I'm trying to write a new file inside a grunt-search callback.
The process takes and object, traverses through it for some data, creates a new array, and then writes that array to a JSON file. The writing part isn't working out so well...
// onComplete is the callback, job is a returned object.
onComplete: function(job) {
console.log("Creating file \"localize_template\"...");
var fs = require('fs');
var localArray = {};
var foundEntries = job.matches;
var stringCount = 0;
// Drill down to the strings that matched the search.
for (var foundEntry in foundEntries) {
// Stay on target...
if (foundEntries.hasOwnProperty(foundEntry)) {
var singleEntry = foundEntries[foundEntry];
// Almost...there...
for( var match in singleEntry ) {
if (singleEntry.hasOwnProperty(match)) {
// Direct hit! We've drilled down to the match string itself.
var theMatch = singleEntry[match].match;
// Now, get the terms inside the strings that were referenced.
var terms = theMatch.match(/".*?"/g);
// Iterate through those strings and add them as entries in the localArray.
for( var i=0; i<terms.length; i++ ) {
var term = terms[i].replace(/"/g, '');
localArray[term] = 'xx:'+term;
stringCount++;
}
}
}
}
}
fs.writeFile( 'i18n/localize_template.json', localArray, {encoding: 'utf8'}, function(err){
console.log("File localize_template.json create successfully.");
if(err) {
throw err;
} else {
console.log("File localize_template.json create successfully.");
}
});
}
The file is being created, but it's blank. I've tried using a generic Hello World!
string instead of localArray
to test, but the file is still blank.
Upvotes: 16
Views: 21061
Reputation: 1
writeFile and writeFileSync is not an atomic operation.
node-js-fs-writefile-empties-the-file
Upvotes: 0
Reputation: 13621
By 2020, in a async
function, use await
as follows:
try {
// blah blah
// Write data to the file
await fs.writeFile(path, data, function (err) {
if (err) {
console.error(`An error occurred while writing data to the file: ${err.message}`)
throw err
}
})
// blah blah
}
catch(err) {
console.error(`An error occurred while writing data to the file: ${err.message}`)
}
Upvotes: 2
Reputation: 121
Try to find out if your code has
process.exit()
For some reason, I have one temperately for testing only. If you do, comment out this one and you will be good to go. My version is v8.6.0.
Upvotes: 6
Reputation: 3708
You need to use the synchronous version:
fs.writeFileSync("./output.txt", "file contents");
Upvotes: 20
Reputation: 31
Your problem should be that the fs.writeFile starts "asynchronous". Try to change the localArray in here (hardcode it to see if it works):
fs.writeFile( 'i18n/localize_template.json', localArray, callback)
And there it should work. The solution i think it is that you should use fs.writeFileSync, or to initialize the localArray outside the oncomplete function, before it starts.
Upvotes: 2
Reputation: 8316
To answer more clearly, fs.writeFile
is asynchronous and the top level grunt stuff doesn’t know to wait for asynchronous operations started by onComplete
. You need to figure out how to tell grunt that you have an unfinished asynchronous operation, except this is a feature that grunt-search
doesn’t support. Otherwise, when you return from onComplete
, grunt-search
will mark the task as done immediately and grunt will exit causing the node process to exit before the asynchronous write completes.
Another thought is to use grunt.file.write()
. This is a synchronous API, so it won’t require you solve the problem of being unable to tell grunt that your task isn’t done. Also, using this API will make your code magically support grunt’s --no-write
option by being a no-op when the user requests a dry run.
onComplete: function (matches) {
grunt.file.write('test', JSON.stringify(matches));
},
Upvotes: 9