Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js TypeError: path must be a string or Buffer

I'm writting a command line program which calculates the total price of an order, using info from a CSV file.

Data inside sample.catalog.csv:

P1,5,1000.00
P2,8,250.00
P3,15,125.00
P4,10,250.00
P5,2,2500.00

And the program must run from the command line with the following arguments:

Example: $ CalculateOrder sample.catalog.csv P1 2 P2 4

(P4 6 P10 5 P12 1 are products and quantity available from csv file)

Total: 4151,25

This is what I have at the moment:

var program = require('commander');
const csv = require('csv');
const fs = require('fs');


program
    .version('1.0.0')
    .option('-l, --list [list]', 'list of order prices in sample.catalog.csv')
    .parse(process.argv)

console.log("hello world")
console.log("list of order prices", program.list);


/* 
    To read csv file and print the data to the console:
    [node orderPrice --list input/sample.catalog.csv]
*/

let parse = csv.parse;
let stream = fs.createReadStream(program.list)
    .pipe(parse({ delimiter: ',' }));

var total = 0;
const vat = 23;
const totalWithVat = total * vat;

stream
.on('data', function (data) {
    let product = data[0];
    let quantity = data[1];
    let price = data[2];
    console.log(product, quantity, price);
    calculateOrder = () => {
        if (quantity > 20) {
            stream.destroy(new Error("Quantity exceeds stored amounts"));
        }
        total += price * quantity;
    }
})

.on("finish", function () {
    console.log("Total price:", totalWithVat);
})

.on("error", function (error) {
    console.error("The following error occured:", error);
})

I am having the following error:

λ node orderPrice calculateOrder sample.catalog.csv P1 2 P2 4
hello world
list of order prices undefined
fs.js:636
binding.open(pathModule._makeLong(path),
      ^

TypeError: path must be a string or Buffer
    at Object.fs.open (fs.js:636:11)
    at ReadStream.open (fs.js:1982:6)
    at new ReadStream (fs.js:1969:10)
    at Object.fs.createReadStream (fs.js:1923:10)
    at Object.<anonymous> (E:\order-price\orderPrice.js:31:17)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)

I'm a Node.js newbie and any help is appreciated. Thank you.

like image 657
RCohen Avatar asked Aug 04 '18 15:08

RCohen


2 Answers

Change line

let stream = fs.createReadStream(program.list)

to

let stream = fs.createReadStream(program.argv[some number])

where some number is position at which you mention filename

e.g. run program with following command

node test.js somevar filename

then somenumber = 3

0th param > node
1st param > test.js (file to run)
2nd > somevar
3rd > filename

Another error:

Final code will look like

const csv = require('fast-csv');
const fs = require('fs');

console.log("hello world")
console.log("list of order prices", process.argv[2]);
let required_products=[]
for(var i=3;i<process.argv.length;){
   let temp=[]
   temp.name=process.argv[i++]
   temp.quantity=process.argv[i++]
   required_products.push(temp)
}
/*
    To read csv file and print the data to the console:
    [node orderPrice --list input/sample.catalog.csv]
*/

let stream = fs.createReadStream(process.argv[2]);

var total = 0;
var csvStream = csv()
    .on("data", function(data){
         let product_name = data[0];
         let quantity = data[1];
         let price = data[2];

         required_products.forEach(function(product){

             if(product['name']==product_name){
               if(parseInt(product['quantity'])>parseInt(quantity)){
                 console.log('Quantity required for product '+product['name']+' '+product['quantity']+' is greater than available '+quantity);
                 process.exit(1)
               }else{
                 total += parseInt(price) * parseInt(product['quantity']);
               }
             }
         })
    })
    .on("end", function(){
         console.log("done");
         let totalWithVat = total * (1+ 0.23);
         console.log("Total price:", totalWithVat);
    }).on("error", function (error) {
        console.error("The following error occured:", error);
    })
 stream.pipe(csvStream);
like image 57
Shubham Avatar answered Oct 19 '22 03:10

Shubham


It may sound glib, but program.list is undefined, which is why you can't read from it. It is undefined because you haven't set up commander to know how it maps from the command line. If you review examples in the commander documentation it might provide more light (and look at the help for "variadic arguments"). You can follow this example on how to use command and action methods.

I recommend if you are just starting, don't use packages like commander if you don't need to. Your question really is about using commander. This question provides some great hints as to how to get at command line arguments.

like image 44
Micromuncher Avatar answered Oct 19 '22 05:10

Micromuncher