-1

I am trying to get the path of the file that I am writing as below. help me with code how to get the path from the below function.

I need the file path as the return variable. I am passing a number as barcodeSourceNumber.

pathToFile = build_barcode('123456789');

function build_barcode(barcodeSourceNumber) {
 var pngFileName;
  const bwipjs = require('bwip-js');

  bwipjs.toBuffer({
    bcid: 'code128',       // Barcode type
    text: barcodeSourceNumber,    // Text to encode
    scale: 3,               // 3x scaling factor
    height: 10,              // Bar height, in millimeters
    includetext: false,     // Show human-readable text
    textxalign: 'center',   // Always good to set this
  }, function (err, png) {
    var pngFileName = = barcodeSourceNumber + '.png';
    fs.writeFileSync(pngFileName, png);
  });

  return pngFileName;
}

But I am getting '.' or undefined as the return value when I try to call the function.

Shiva Nara
  • 81
  • 1
  • 2
  • 10
  • Presumably, this is because you are trying to reference `pngFileName` in this ` return path.dirname(pngFileName);` BEFORE `bwip-js.toBuffer()` has finished and called it's callback where you set `pngFileName`. So, this is a timing problem. If `bwip-js.toBuffer()` is indeed asynchronous, then you cannot directly return anything related to its result because your function will return before the asynchronous callback gets called. Instead, you will need to communicate the return value back via a callback or a promise. – jfriend00 Oct 09 '20 at 21:16
  • thanks, could you provide some code to my existing one, I tried many ways but it is still giving me '.' – Shiva Nara Oct 09 '20 at 22:58
  • Please provide expected input and output. It is not clear to me what you're trying to accomplish. What do you pass this function (give a specific example of a `barcodeSourceNumber`)? What exactly do you expect the function to return or communicate back to the caller? Why are you using `.dirname()` at the end? It looks to me like your local `pngFileName` will just be a plain filename with no path on it. – jfriend00 Oct 10 '20 at 00:43
  • You didn't answer most of my questions. Please read my comment again and answer all the questions there. You are starting with a filename that has no path so it is natural that `path.dirname()` would have NO path to give you. With an input of `'123456789'`, what do you expect the output to be and why are you using `path.dirname()` on a filename that has no path on it? Also, we need to know if `bwipjs.toBuffer()` is synchronous or asynchronous? It has an asynchronous looking callback, so that would be my guess. But, either way, that affects how you return data from the function. – jfriend00 Oct 10 '20 at 03:38
  • I am trying to get the whole path for the newly created file from fs.writeFileSync(pngFileName, png); as my output in a String – Shiva Nara Oct 11 '20 at 05:30

3 Answers3

0

That's what promise does

function build_barcode(barcodeSourceNumber) {
  var pngFileName;
  const bwipjs = require("bwip-js");

  return new Promise((res, rej) => {
    bwipjs.toBuffer(
      {
        bcid: "code128", // Barcode type
        text: barcodeSourceNumber, // Text to encode
        scale: 3, // 3x scaling factor
        height: 10, // Bar height, in millimeters
        includetext: false, // Show human-readable text
        textxalign: "center", // Always good to set this
      },
      function (err, png) {
        /* error handling  */
        /* if (err) {
          rej(err)
        } */

        var pngFileName = barcodeSourceNumber + ".png";
        fs.writeFileSync(pngFileName, png);
        res(pngFileName);
      }
    );
  });
}

pathToFile = build_barcode("123456789").then((res) => {
  console.log(`pngFileName: ${res}`);
});

0

Of course I'm not sure whether bwipJs.toBuffer is asynchronous or not. You can also try the following methods


pathToFile = build_barcode("123456789");

function build_barcode(barcodeSourceNumber) {
  var pngFileName;
  const bwipjs = require("bwip-js");

  bwipjs.toBuffer(
    {
      bcid: "code128", // Barcode type
      text: barcodeSourceNumber, // Text to encode
      scale: 3, // 3x scaling factor
      height: 10, // Bar height, in millimeters
      includetext: false, // Show human-readable text
      textxalign: "center", // Always good to set this
    },
    function (err, png) {
      pngFileName = barcodeSourceNumber + ".png";
      fs.writeFileSync(pngFileName, png);
    }
  );

  return pngFileName;
}


0

This is what I would suggest you do:

const bwipjs = require('bwip-js');
const fs = require('fs');

async function build_barcode(barcodeSourceNumber) {
    // use promise version of .toBuffer()
    const pngData = await bwipjs.toBuffer({
        bcid: 'code128', // Barcode type
        text: barcodeSourceNumber, // Text to encode
        scale: 3, // 3x scaling factor
        height: 10, // Bar height, in millimeters
        includetext: false, // Show human-readable text
        textxalign: 'center', // Always good to set this
    });
    // combine filename with file extension and turn it into an absolute path
    const pngFileName = path.resolve(barcodeSourceNumber + '.png');
    await fs.promises.writeFile(pngFileName, pngData);
    // make final resolved value be the full filename
    return pngFileName;
}

build_barcode('123456789').then(result => {
    console.log(result);
}).catch(err => {
    console.log(err);
});

Changes:

  1. Use promise version of bwipjs.toBuffer() to make it simpler to communicate back asynchronous result
  2. Switch to fs.promises.writeFile() since we're already using promises and are already asynchronous
  3. Move require() out of the asynchronous flow, since it's blocking
  4. Using async for the function so we can use await and more simply sequence multiple asynchronous operations.
  5. Use path.resolve() to get the full, absolute path from our filename.
  6. Make build_barcode() return a promise so we can more easily communicate back the filename at the end of several asynchronous operations.
  7. If the caller wants just the directory name associated with the returned filename, then it can use path.dirname() on the whole pathname to get just the directory.
jfriend00
  • 683,504
  • 96
  • 985
  • 979