0

I know, this is something old. There are many questions regarding to this. But none of them didn't guide me or didn't gave me the actual concept. My case is:

     if something
       render something
     else
       render somethingAnother

Why is this logic generates this error enter image description here

After 1st execution, I'm not able to continue this process (I could continue for a while, but after some time error will come), by pressing back button of browser and then returning back to the home page. Everytime I should restart my server using node command. Why headers won't reset if I press back button of browser, how to do some header reset or something which will correct my logic.

    const cv = require('opencv4nodejs');
    var async = require('async');
    var OrderID;
    var OrderNo;
    var compare = 0;
    var CompanyName;
    var notSimilar = 0;
    const download = require('image-downloader')
    const distanceThreshold = 30;
    var url;
    var FolderPath;
    var isSimilar = 0;
    var j = 0;
    var image1;
    var dbPath;
    var filterCount = 0;
    var image2;
    var dbImgCount = 0;
    var express = require('express');
    var request = require('request');
    var app = express();
    app.set('view engine', 'pug')
    var multer = require('multer');

    var storage = multer.diskStorage({
      destination: function (req, file, callback) {
      callback(null, './');
    },
    filename: function (req, file, callback) {
    callback(null, file.fieldname + '-' + Date.now());
   }
  });

  var upload = multer({ storage : storage}).single('userPhoto');

  const sql = require("mssql");


 var config = {
user: '***',
password: '****',
server: '192.168.5.100\\SQLEXPRESS', 
database: 'Test_MatdesignDB1',
connectionTimeout: 300000,
requestTimeout: 300000,
pool: {
    idleTimeoutMillis: 300000,
    max: 100
   }
  };


 sql.connect(config).then(pool => { 
        return pool.request()
      .query('select count(*) from OrderImageUpload; select FolderPath from OrderImageUpload;')
  }).then(result => {
var a = JSON.stringify(result.recordset[0]);
        dbImgCount = a.slice(4,6);
FolderPath = result.recordsets[1];
sql.close();
 }).catch(err => {
     console.log(err);
    sql.close();
   })


    app.get('/',function(req,res){

        res.sendFile(__dirname + "/index.html");


    });

  app.post('/api/photo',function(req,res){
compare = 1;
upload(req,res,function(err) {
    if(err) {
        console.log(err);
        res.send("File uploading error");
    }
    else{
     // console.log("Success");
      image1 = req.file.filename;


      var matchFeatures = ({ url, img1, img2, detector, matchFunc }) => {

        // detect keypoints
        const keyPoints1 = detector.detect(img1);
        const keyPoints2 = detector.detect(img2);


        // compute feature descriptors
        const descriptors1 = detector.compute(img1, keyPoints1);
        const descriptors2 = detector.compute(img2, keyPoints2);

        // match the feature descriptors
        const matches = matchFunc(descriptors1, descriptors2);

       // only keep good matches
        const bestN = 40;
        const bestMatches = matches.sort(
          (match1, match2) => (match1.distance - match2.distance)
          ).slice(0, bestN);

        //console.log(bestMatches);


        for(var i=0; i<bestN; i++){

          if((bestMatches[i].distance) <= (distanceThreshold)){
            filterCount++;

          }
        }
        if(filterCount >= (bestN/4))
           isSimilar = 1;
        if(isSimilar){
          notSimilar = 0;
          filterCount = 0;
          isSimilar = 0;
          console.log("Similar images\n");
          dbPath = url;
          sql.close();
          (async function() {
            try {
              let pool = await sql.connect(config)
              let result1 = await pool.request()
              .query("select OrderID from Test_MatdesignDB1.dbo.OrderImageUpload where FolderPath = '"+dbPath+"';")
              OrderID = result1.recordset[0].OrderID;

              let result2 = await pool.request()
              .query('select OrderNo , CompanyName from Test_MatdesignDB1.dbo.[Order] where OrderID = '+OrderID);

              OrderNo = result2.recordset[0].OrderNo;
              CompanyName = result2.recordset[0].CompanyName;
              res.render('similar', { title: 'Similar', CompanyName: CompanyName, OrderID: OrderID, OrderNo: OrderNo, img_path_var : dbPath }) //Render number 1 in 'if' case
              } catch (err) {
                  console.log(err);
                  sql.close();
                }
              sql.close();
          })()

          sql.on('error', err => {
            console.log(err);
          })
          }
          else{
            isSimilar = 0;
            filterCount = 0;
            notSimilar++;
            if(notSimilar >= (dbImgCount ))
            {
              notSimilar = 0;
              res.render('notSimilar', { title: 'Not Similar', message: 'No Similar Images' }) //Render number 2 in 'else' case
            }
            console.log("Not similar\n");
          }


        return cv.drawMatches(
            img1,
            img2,
            keyPoints1,
            keyPoints2,
            bestMatches
        );
      };


      for (j=0; j<dbImgCount; j++) {

        (function(j) {
          async.waterfall([
            async function downloadIMG(done) {
              try {
                  var options = {
                    url:  FolderPath[j].FolderPath,
                    dest: '/home/ubuntu/imgCompare/DBimages/'                
                    }
                  const { filename, image } =  await download.image(options);
                  return [filename, options.url];

                  } catch (e) {
                      console.error(e)
                  }


            },
            async function featureMatching([a, MatchURL], done){
              const img1 = cv.imread(image1);
              url = MatchURL;;
              const img = a.slice(33);
              const img2 = cv.imread('./DBimages/'+img);

              const orbMatchesImg = matchFeatures({
                url,
                img1,
                img2,
                detector: new cv.ORBDetector(),
                matchFunc: cv.matchBruteForceHamming
              });

              done(null);
            }


          ],
        function (err) {});
        })(j);
      }
      }
     });
    });


    app.listen(5000,function(){
       console.log("Working on port 5000");
  });
George T Kurian
  • 183
  • 2
  • 12
  • Possible duplicate of [Error: Can't set headers after they are sent to the client](https://stackoverflow.com/questions/7042340/error-cant-set-headers-after-they-are-sent-to-the-client) – Mukesh Sharma Jul 30 '18 at 13:44

3 Answers3

0

You need to add return before rendering a view. It's happening because the view rendering is happening more than 1 time there must be a condition in your code which is letting views to render multiple times. Add this return statement:

return res.render();
Zeeshan Tariq
  • 604
  • 5
  • 10
0

You're getting this error because you're calling matchFeatures() multiple times within a for loop.

app.post('/api/photo', function (req, res) {
  var matchFeatures = ({url, img1, img2, detector, matchFunc}) => {
    if (isSimilar) {
      res.render('similar', {
        title: 'Similar',
        ...
      }) //Render number 1 in 'if' case
    } else {
      res.render('notSimilar', {
        title: 'Not Similar',
        message: 'No Similar Images'
      }) //Render number 2 in 'else' case
    }
  };

  for (j = 0; j < dbImgCount; j++) {
    async function featureMatching() {
      const orbMatchesImg = matchFeatures({ // since you're calling it multiple times here
        url,                                  // matchFeatures() will attempt to send
        img1,                                // responses multiple times
        img2,
        detector: new cv.ORBDetector(),
        matchFunc: cv.matchBruteForceHamming
      });
    }
  }
});

To fix this, You need to consolidate all these responses and send to client only once.

Sridhar
  • 11,466
  • 5
  • 39
  • 43
0

I figured out the error. I didn't reset the variable notSimilar at the entry point.

Done resetting of notSimilar as below, no error! Thanks Everyone.

     app.post('/api/photo',function(req,res){
          notSimilar = 0;
George T Kurian
  • 183
  • 2
  • 12