Rocking chief
Rocking chief

Reputation: 1069

Word frequency count in javascript?

I am learning javascript and right now I am trying to get the word frequency count from an array of strings in my express node.js backend. My code looks like:

  upload(req, res, function(err) {
    if (err) {
        console.log(err);
        return res.end('Error');
    } else {
        console.log(req.body);
        req.files.forEach(function(item) {
            const data = fs.readFileSync(item.path);
            pdfText(data,  function(err, chunks) {
                chunks.forEach(function(item, index){
                  newitem = item.split(" ");
                  newitem.forEach(function(item, index){

                  });
                });
            });

        });
        // no output at this point
        console.log(dictCount);

        res.end('File uploaded');
    }
});

When I do a console.log(dictCount), there's no output. I tried to debug the code by doing console.log inside the if(item.match) clause but that would crash the express app. I am frustrated about why this even happens? Can someone please provide some hints on this? Thanks a lot!

Upvotes: 0

Views: 1067

Answers (1)

Catalyst
Catalyst

Reputation: 3247

I called out the problem I think I see:

upload(req, res, function(err) {
    if (err) {
        console.log(err);
        return res.end('Error');
    } else {
        console.log(req.body);
        req.files.forEach(function(item) {
            const data = fs.readFileSync(item.path);
            pdfText(data,  function(err, chunks) { // asynchronous
                chunks.forEach(function(item, index){ // runs later
                  newitem = item.split(" ");
                  newitem.forEach(function(item, index){
                    if(item.match(/^[a-z0-9]+$/i)){
                      if(item in dictCount){
                        dictCount[item].count++;
                        // console log here crash the app
                        //console.log(item);
                        //console.log(dictCount[item]);
                      }else{
                        dictCount[item]={word: item, count:0};
                      }
                    }
                  });
                });
            });

        });
        // no output at this point
        console.log(dictCount); // runs immediately, before the "runs later" part

        res.end('File uploaded');
    }
});

and this might work instead:

Also, here is a sample using the npm bluebird module and node 8+ async/await to reduce the code:

upload(req, res, async err => {
  try {
    if (err) {
      console.log(err);
      return res.end('Error');
    } else {
      console.log(req.body);
      await bluebird.each(req.files, async item => {
        const data = fs.readFileSync(item.path);
        const chunks = await bluebird.fromCallback(cb => pdfText(data, cb));
        chunks.forEach((item, index) => {
          newitem = item.split(" ");
          newitem.forEach((item, index) => {
            if (item.match(/^[a-z0-9]+$/i)) {
              if (item in dictCount) {
                dictCount[item].count++;
                // console log here crash the app
                //console.log(item);
                //console.log(dictCount[item]);
              } else {
                dictCount[item] = { word: item, count: 0 };
              }
            }
          });
        });
      });
      console.log(dictCount);
      res.end('File uploaded');
    }
  } catch (e) {
    res.end('Error')
  }
});

EDIT: removed the example that didn't work.

Upvotes: 2

Related Questions