简体   繁体   中英

Why do I get “TypeError: object is not a function” running this example node.js code?

Why do I get an error running the code shown below ? (It's used in one of the homework's in the Stanford 'Startup engineering' course on Coursera: https://class.coursera.org/startup-001/quiz/attempt?quiz_id=149 )

The course ran in june-sept 2013, so there may have been updates to node or csv that have broken the script, perhaps? The homework is not about fixing the script, so this question is not a 'cheat', and the course is not currently running anyway..

So, the environment is: Ubuntu 14.04 (kernel 3-13-0-29-generic), node v0.11.13, npm v1.4.9

And I have npm install 'd csv, accounting util and restler in the home directory, and the script is there too.

This has me completely stumped.... :-(

error message:

[ubuntu@ip-xxx-xxx-xxx-xxx:~]$node market-research.js
Invoked at command line.
Wrote market-research.csv
Symbol  Name    Market Cap      Previous Close Price    P/E Ratio       Shares  EPS   Earnings
/home/ubuntu/market-research.js:47
    csv()
    ^
TypeError: object is not a function
    at csv2console (/home/ubuntu/market-research.js:47:5)
    at Request.response2console (/home/ubuntu/market-research.js:65:13)
    at Request.EventEmitter.emit (events.js:110:17)
    at Request.mixin._fireSuccess (/home/ubuntu/node_modules/restler/lib/restler.js:226:10)
    at /home/ubuntu/node_modules/restler/lib/restler.js:158:20
    at IncomingMessage.parsers.auto (/home/ubuntu/node_modules/restler/lib/restler.js:394:7)
    at Request.mixin._encode (/home/ubuntu/node_modules/restler/lib/restler.js:195:29)
    at /home/ubuntu/node_modules/restler/lib/restler.js:154:16
    at Request.mixin._decode (/home/ubuntu/node_modules/restler/lib/restler.js:170:7)
    at IncomingMessage.<anonymous> (/home/ubuntu/node_modules/restler/lib/restler.js:147:14)
[ubuntu@ip-xxx-xxx-xxx-xxx:~]$

code:

    #!/usr/bin/env node
    /*
    Use the Yahoo Finance CSV API to do some basic market research calculations.

     - Background: http://greenido.wordpress.com/2009/12/22/yahoo-finance-hidden-api/
     - Example URL: http://finance.yahoo.com/d/quotes.csv?s=GOOG+FB+AAPL&f=snj1pr
        s:  Symbol
        n:  Name
        j1: Market Capitalization (in billions)
        p:  Price-per-share (at previous close)
        r:  Price to Earnings Ratio

    Further references.

     - https://github.com/danwrong/restler
     - https://github.com/wdavidw/node-csv
     - http://josscrowcroft.github.io/accounting.js
     - http://stackoverflow.com/questions/4981891/node-js-equivalent-of-pythons-if-name-main
     - http://nodejs.org/docs/latest/api/util.html#util_util_format_format

    */

    var util = require('util');
    var fs = require('fs');
    var rest = require('restler');
    var csv = require('csv');
    var accounting = require('accounting');
    var CSVFILE_DEFAULT = "market-research.csv";
    var SYMBOLS_DEFAULT = ["GOOG", "FB", "AAPL", "YHOO", "MSFT", "LNKD", "CRM"];
    var COLUMNS_DEFAULT = 'snj1pr'; // http://greenido.wordpress.com/2009/12/22/yahoo-finance-hidden-api
    var HEADERS_DEFAULT = ["Symbol", "Name", "Market Cap", "Previous Close Price", 
                           "P/E Ratio", "Shares", "EPS", "Earnings"];

    var financeurl = function(symbols, columns) {
        return util.format(
            'http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s',
            symbols.join('+'),
            columns);
    };

    var marketCapFloat = function(marketCapString) {
        return parseFloat(marketCapString.split('B')[0]) * 1e9;
    };

    var csv2console = function(csvfile, headers) {
        console.log(headers.join("\t"));
        csv()
        .from.path(csvfile)
        .on('record', function(row, index) {
            var shares = Math.round(marketCapFloat(row[2])/row[3], 0);
            var eps = (row[3]/row[4]).toFixed(3);
            var earnings = accounting.formatMoney(eps * shares);
            outrow = row.concat([shares, eps, earnings]);
            console.log(outrow.join("\t"));
        });
    };

    var buildfn = function(csvfile, headers) {
        var response2console = function(result, response) {
            if (result instanceof Error) {
                console.error('Error: ' + util.format(response.message));
            } else {
                console.error("Wrote %s", csvfile);
                fs.writeFileSync(csvfile, result);
                csv2console(csvfile, headers);
            }
        };
        return response2console;
    };

    var marketResearch = function(symbols, columns, csvfile, headers) {
        symbols = symbols || SYMBOLS_DEFAULT;
        columns = columns || COLUMNS_DEFAULT;
        csvfile = csvfile || CSVFILE_DEFAULT;
        headers = headers || HEADERS_DEFAULT;
        var apiurl = financeurl(symbols, columns);
        var response2console = buildfn(csvfile, headers);
        rest.get(apiurl).on('complete', response2console);
    };

    if(require.main == module) {
        console.error('Invoked at command line.');
        var symbols = process.argv;
        if(symbols.length > 2) {
            symbols = symbols.slice(2, symbols.length);
        } else {
            symbols = undefined;
        };
        marketResearch(symbols);
    } else {
        console.error('Invoked via library call');
    }

    exports.marketResearch = marketResearch;

contents of market-research.csv created by the script:

    "GOOG","Google Inc.",386.6B,569.20,29.49
    "FB","Facebook, Inc.",194.5B,73.855,78.49
    "AAPL","Apple Inc.",613.8B,102.25,16.49
    "YHOO","Yahoo! Inc.",38.302B,38.31,33.11
    "MSFT","Microsoft Corpora",374.3B,44.88,17.06
    "LNKD","LinkedIn Corporat",27.747B,223.26,N/A
    "CRM","Salesforce.com In",36.577B,58.29,N/A

Quantas 94 Heavy, thanks for the hint.

12 months ago, node-csv was at version 0.2, but it is now at 0.4 and the API has changed.

I've now written the csv-console function as follows:

// part of file market-script.js
// edited by Jeff Moye (Moyesoft)
// no attribution in the original file

var csv2console = function(csvfile, headers) {
  console.log(headers.join("\t"));
  var parser = csv.parse();    //create the parser                                                                                                            

  parser.on('readable', function(){    //the 'record' event no longer exists                                                                                  
                                       // so instead we write a handler for the                                                                               
                                       // 'readable' event                                                                                                    
    while(record = parser.read()){     // and read() each record in a loop                                                                                                                  
      var shares = Math.round(marketCapFloat(record[2])/record[3], 0);
      var eps = (record[3]/record[4]).toFixed(3);
      var earnings = accounting.formatMoney(eps * shares);
      outrow = record.concat([shares, eps, earnings]);
      console.log(outrow.join("\t"));
    }
  });

  parser.on('error', function(err){    // we may as well have an error handler                                                                                
    console.log(err.message);
  });

  fs.createReadStream(csvfile).pipe(parser);    //open file as a stream and pipe it to the parser                                                             
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM