0

This function does not return a promise.

It uses the csvtojson module. https://www.npmjs.com/package/csvtojson

var CSVConverter=require("csvtojson").Converter;

function get_json(cvs_file_location)
{
    var data=fs.readFileSync(cvs_file_location).toString();
    var csvConverter=new CSVConverter();

    csvConverter.fromString(data,function(err,jsonObj){
        if (err){
            console.log("error msg: " + err);
            return null;
        }

        var json_csv = clone_obj(jsonObj);
        console.log(json_csv);
        return json_csv;
    });
}

I would like to convert it into one that returns a promise. This is what I wrote;

var Promise = require('bluebird');
var Converter = Promise.promisifyAll(require("csvtojson").Converter);

function get_json(cvs_file_location)
{
    var data=fs.readFileSync(cvs_file_location).toString();

    return new Converter().fromStringAsync(data)
        .then(function(csvString){
            var json_csv = clone_obj(csvString);
            console.log(json_csv);
            return json_csv;
        })
        .catch(function(cb) {
            console.log("error msg: " + cb);
            return null;
        });
}

Unfortunately, it does not work. The error message looks like this;

return new Converter().fromStringAsync(data)
                       ^ TypeError: (intermediate value).fromStringAsync is not a function

What is wrong with the code? Or is there another way to write the code to return a promise?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
guagay_wk
  • 26,337
  • 54
  • 186
  • 295
  • What if you wrap `new Converter()` with parentheses: `(new Converter()).fromStringAsync` ? – zerkms Nov 07 '15 at 06:41
  • Unfortunately, still the same error – guagay_wk Nov 07 '15 at 06:42
  • `fromStringAsync` method doesn't exist in that module – michelem Nov 07 '15 at 07:00
  • I thought `promisifyAll` will add `fromStringAsync` method to the module? – guagay_wk Nov 07 '15 at 07:02
  • @user768421 - why would promisifyAll **add** an arbitrary method to a module? - did you try `fromString` instead? - you even **accepted** the answer earlier - https://stackoverflow.com/questions/33577646/promisifying-a-function-with-bluebird which clearly uses `fromString().then` – Jaromanda X Nov 07 '15 at 07:08
  • Yes, when I tried that answer, it did not work. Thought a little change would do the trick. I tried different variations, including `fromString` but couldn't get it to work. So, I am seeking help from experts here again. – guagay_wk Nov 07 '15 at 07:19
  • 1
    "I thought promisifyAll will add fromStringAsync method to the module?" - `Promise.promisifyAll(require("csvtojson").Converter)` will promisify only Converter's static methods, not methods of instances created with `new Converter()`;. Try promisifying Converter's prototype `var Converter = require("csvtojson").Converter; Promise.promisifyAll(Converter.prototype);`. If that doesn't work, then you will have to promisify every instance after it is created, which is expensive unless there's a way to work with a single instance. – Roamer-1888 Nov 07 '15 at 08:57
  • 1
    Also, remember that `.promisifyAll()` is selective. It sniffs out methods that are promisifiable and leaves others alone. Are you sure that `.fromString()` will promisify? – Roamer-1888 Nov 07 '15 at 09:03
  • @Roamer-1888 very good hints. Let me try them out. Hopefully, I can post the answer later. – guagay_wk Nov 07 '15 at 09:11
  • @Roamer-1888: how do you think `promisifyAll` selects "promisifyable" methods? – Bergi Nov 07 '15 at 13:04

1 Answers1

2

You have to promisify the prototype of Converter because of it being a constructor. Regular var Converter = Promise.promisifyAll(require('csvtojson').Converter)); would work if the Converter object directly had the functions to be promisified (as is the case with most APIs).

var fs = require('fs');
var Promise = require('bluebird');
var Converter = require('csvtojson').Converter;
Promise.promisifyAll(Converter.prototype);

var converter = new Converter();
converter.fromStringAsync(fs.readFileSync('foo.csv', 'utf8'))
  .then(console.log)
raine
  • 1,694
  • 17
  • 14