1

I am trying to combine multiple textfiles,convert them in a single zip file using zip archiver.

   exports.downloadFilesInZip = function(req, res, next) {

var respObj = {};
var file_names = [];
    var projectId = 111;
    var file_ids = 11111;
    console.log(projectId);
    db.getConnection(function (err, connection) {
        if (err) {
            debug(err);
            next(err);
        }
        else {
            var updateQuery = "select data from file_data where file_id IN (?)";
            console.log(updateQuery);
            connection.query(updateQuery,[file_ids], function (err, results) {
                console.log("inside" + updateQuery);

                if (err) {
                    connection.release();
                    console.log("error" + JSON.stringify(err));
                    debug(err);
                    next(err);
                }
                else {
                    async.eachSeries(results,function(item,loopCallBack){
                        var text = "";
                        console.log("hllllllll");
                        console.log(item.data);
                        console.log(JSON.parse(item.data));
                        document_text = JSON.parse(item.data);
                        console.log("dssddssdsdsdsdsd"+document_text);
                        for(var j=0; j < document_text.length ;j++)
                        {
                            text += document_text[j]['text'];
                        }

                        //file_names.push(convertStringToTextFile(text));
                        convertStringToTextFile(text,function(err,file_name){
                            if(err){
                                console.log(err);
                                loopCallBack(err);
                            }
                            else {
                                file_names.push(file_name);
                                loopCallBack();
                            }
                        })

                    },function(err){
                        if(err){
                            console.log(err);
                            next(err);
                        }
                        else {
                            var updateQuery = "select name from project where id in (?)";
                            console.log(updateQuery);
                            connection.query(updateQuery,[projectId], function (err, results) {
                                console.log("inside" + updateQuery);
                                connection.release();
                                if (err) {
                                    console.log("error" + JSON.stringify(err));
                                    debug(err);
                                    next(err);
                                }
                                else {
                                    var fileName_link = JSON.stringify(results[0].name);

                                    console.log("projectname"+fileName_link);
                                    convertTextFilesToZip(file_names,fileName_link, function (err, filename) {
                                        if (err) {
                                            console.log(err);
                                            next(err);
                                        }
                                        else {
                                            console.log("filename link" + filename);
                                            res.json({
                                                status: 0,
                                                file_link: filename
                                            });
                                        }
                                    });
                                }
                            });
                        }

                    });

                }
            });

        }
    });
}

}

convertStringToTextFile = function(text,cb){
var json_filename = 'tmp/file_'+uuid.v4().replace('-','')+'.txt';
fs.writeFile(json_filename, text , function (err) {
    if (err) {
        debug(err);
        cb(err);
    }
    else{
        cb(null,json_filename);
    }
});

};

convertTextFilesToZip = function(textFiles,file_link,cb){
console.log("textfiles"+textFiles);
var filename = 'reports/'+JSON.parse(file_link)+'_extractedText.zip';
var output = fs.createWriteStream(filename);

output.on('close', function() {
    console.log(zipArchive.pointer() + ' total bytes');
    console.log('archiver has been finalized and the output file descriptor has closed.');
});

zipArchive.on('error', function(err) {
    cb(err);
});

zipArchive.pipe(output);

zipArchive.bulk([
    { expand: true, src: textFiles }
]);

zipArchive.finalize();
cb(null,filename);


}

It works okay the first time and after that it throws this error.I have checked other posts in which res is returned twice but i couldn't find it.It says that can't set headers after they are sent.I think the problem is in the convertTextFilesToZip function but i cant seem to pinpoint the exact location which is generating the error.ANy help is appreciated.

  Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:350:11)
at ServerResponse.header     (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/response.js:700:10)
at ServerResponse.send (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/response.js:154:12)
at fn (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/response.js:934:10)
at View.exports.renderFile [as engine] (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/jade/lib/index.js:374:12)
at View.render (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/view.js:93:8)
at EventEmitter.app.render (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/application.js:566:10)
at ServerResponse.res.render (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/lib/response.js:938:7)
at /Users/zeeshandar/Desktop/Agreements_info/agreements_info/app.js:207:13
at Layer.handle_error (/Users/zeeshandar/Desktop/Agreements_info/agreements_info/node_modules/express/li b/router/layer.js:58:5)
soldiershin
  • 1,612
  • 1
  • 18
  • 29
  • 1
    Wow, if ever there was a textbook case for using promises for a series of async operations to make the code a lot cleaner and a lot easier to handle errors, this would be a great example. – jfriend00 May 02 '16 at 16:04
  • If `convertTextFilesToZip()` where does the variable `zipArchive` come from? – jfriend00 May 02 '16 at 16:05
  • It is initialized in the code i just havent copied it here – soldiershin May 02 '16 at 16:13
  • 1
    Initialized where? It's not initialized in `convertTextFilesToZip()` so it appears you're reusing that variable over and over. Is that a correct implementation? Also, wouldn't all zipArchive operations be async? – jfriend00 May 02 '16 at 16:23
  • @jfriend00 yup you were right that was indeed the problem.Thanks alot..:) – soldiershin May 02 '16 at 16:41

1 Answers1

0

Making my comment into an answer since it appears to have led to the solution.

The variable zipArchive is not initialized in convertTextFilesToZip() therefore you are reusing that variable from one function call to the next and that seems unlikely to be the right implementation.

Also, I would expect your method calls to zipArchive to be asynchronous and it doesn't look like your are coding for that since the callback is called before you have any sort of completion notification.

jfriend00
  • 683,504
  • 96
  • 985
  • 979