Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot initialize project - ibkr() is not a function and node:11784 #48

Closed
saifali96 opened this issue Nov 30, 2020 · 5 comments
Closed

Comments

@saifali96
Copy link

saifali96 commented Nov 30, 2020

The code snippet given in the README.MD is giving several different errors. Tried with a fresh NodeJS TS project.

I spent quite some time tinkering aroud, first it said cannot use import statement outside a module. Here's the error:

(node:11784) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
E:\work\robinhood\exp\exp1ts\dist\app.js:18
import ibkr, { IbkrEvents } from '@stoqey/ibkr';
^^^^^^

SyntaxError: Cannot use import statement outside a module

Later when you change the type to module, it says ibkr() is not a function! Here's the error:

await ibkr();
      ^

TypeError: ibkr is not a function

Even if we decide to change the import to regular require() statement, tsc starts to complain about using TLA/top-level-awaits, because the file is not a module. The error given:

> tsc && node dist/app.js

src/app.ts:32:1 - error TS1375: 'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.

32 await ibkr();

After some tinkering around, I managed to make it work with the following code, which is not very pretty:

const ibkr = require('@stoqey/ibkr');
const { AccountSummary, IBKREVENTS, IbkrEvents, PortFolioUpdate, getContractDetails } = ibkr;

const ibkrEvents = IbkrEvents.Instance;
const IB_HOST = "localhost";
const IB_PORT = 7496;

ibkr.default({ port: IB_PORT, host: IB_HOST })
  .then((v) => {
    const accountId = AccountSummary.Instance.accountSummary.AccountId;
    const totalCashValue = AccountSummary.Instance.accountSummary.TotalCashValue;

    console.log("acc id: " + accountId)
    console.log("cashVal: " + totalCashValue)
    console.log(v)
  })
  .catch((e) => {
    console.log("Connection Failed.");
    console.log(e);
  });

Can you please explain or please create a more detailed get started guide?

Also in my code, or in general, how can I handle/catch and sudden TWS/API connection lost? This is critical, because at the moment the program just ends.

Thanks for your support!

node: 14.15.1
os: win10pro 64bit

@ceddybi
Copy link
Member

ceddybi commented Nov 30, 2020

@saifali96

Turn on esModuleInterop in your tsconfig.json

or simply

import * as ibkr from '@stoqey/ibkr'

@ceddybi
Copy link
Member

ceddybi commented Nov 30, 2020

@saifali96 you basically need to call the initialization only once,

const ib = await ibkr({
    port: IB_PORT,
    host: IB_HOST,
});

if (!ib) {
   // ib failed to start
  // ..... do something to stop your code here
}

else {
     // success
    // the rest of your code here

    // .....

    // IBKR will automatically stop your code with `process.exit(1)` if it loses connection
   
}

@ceddybi ceddybi closed this as completed Nov 30, 2020
@saifali96
Copy link
Author

This has some new issues! :)

The code:

import * as ibkr from '@stoqey/ibkr'

const { AccountSummary, IBKREVENTS, IbkrEvents, PortFolioUpdate, getContractDetails } = ibkr;

const ibkrEvents = IbkrEvents.Instance;
const IB_HOST = "localhost";
const IB_PORT = 7497;


const ib = await ibkr({
  port: IB_PORT,
  host: IB_HOST,
});

if (!ib) {
 // ib failed to start
// ..... do something to stop your code here
}

else {
   // success
  // the rest of your code here

  // .....

  // IBKR will automatically stop your code with `process.exit(1)` if it loses connection
 
}

Error:

yarn run v1.22.10
$ tsc && node dist/app.js
src/app.ts:24:49 - error TS2339: Property 'PortFolioUpdate' does not exist on type 'typeof import("E:/work/robinhood/exp/exp1ts/node_modules/@stoqey/ibkr/dist/index")'.

24 const { AccountSummary, IBKREVENTS, IbkrEvents, PortFolioUpdate, getContractDetails } = ibkr;
                                                   ~~~~~~~~~~~~~~~

src/app.ts:31:18 - error TS2349: This expression is not callable.
  Type 'typeof import("E:/work/robinhood/exp/exp1ts/node_modules/@stoqey/ibkr/dist/index")' has no call signatures.

31 const ib = await ibkr({
                    ~~~~


Found 2 errors.

error Command failed with exit code 2.

My tsconfig.json:

{
    "compilerOptions": {
      "module": "esnext",
      "esModuleInterop": true,
      "target": "es2017",
      "moduleResolution": "node",
      "sourceMap": true,
      "outDir": "dist"
    },
    "lib": ["es2015"]
  }

Even if I remove the reference to PortFolioUpdate or the await ibkr() error exits. When I change the expression to await ibkr.default(), it says file is not a module!

Lastly upon making it a module, await ibkr() still doesn't work, prints the errror:

yarn run v1.22.10
$ tsc && node dist/app.js
src/app.ts:31:18 - error TS2349: This expression is not callable.
  Type 'typeof import("E:/work/robinhood/exp/exp1ts/node_modules/@stoqey/ibkr/dist/index")' has no call signatures.

31 const ib = await ibkr({
                    ~~~~


Found 1 error.

Please advise.

@saifali96
Copy link
Author

saifali96 commented Dec 1, 2020

Another try with the code snippet given in the README.MD:

import ibkr, { AccountSummary, IBKREVENTS, IbkrEvents, PortFolioUpdate, getContractDetails } from '@stoqey/ibkr';

const ibkrEvents = IbkrEvents.Instance;
const IB_HOST = "localhost";
const IB_PORT = 7497;

// 0. Using env process.env.IB_PORT and process.env.IB_HOST
await ibkr();

// 1. Async 
await ibkr({ port: IB_PORT, host: IB_HOST });

// 2. Callback
ibkr({ port: IB_PORT, host: IB_HOST }).then(started => {
  
    if(!started){
          // Error IBKR has not started
          console.log('error cannot start ibkr');
        //   Not to proceed if not connected with interactive brokers
          return process.exit(1);
    }

    // Your code here

})

Error:

$ tsc && node dist/app.js
file:///E:/work/robinhood/exp/exp1ts/dist/app.js:23
await ibkr();
      ^

TypeError: ibkr is not a function
    at file:///E:/work/robinhood/exp/exp1ts/dist/app.js:23:7
    at ModuleJob.run (internal/modules/esm/module_job.js:146:23)
    at async Loader.import (internal/modules/esm/loader.js:165:24)
    at async Object.loadESM (internal/process/esm_loader.js:68:5)
error Command failed with exit code 1.

ibkr() is not a function.

I'm sorry if this is all very stupid for you, but I can't seem to run it properly. Would you please kindly make a more detailed get to started guide for the pacakge? Or make a repo that works and compiles by default? That would be very nice of you.

@ceddybi
Copy link
Member

ceddybi commented Dec 1, 2020

Here is a complete example

// app.ts file
import * as ibkr from '@stoqey/ibkr';
import { getContractDetails, Portfolios } from "@stoqey/ibkr";

async function index() {
    try {
        
        const ib = await ibkr({
            port: IB_PORT,
            host: IB_HOST,
        });

        if (!ib) {
            throw new Error('error connecting to ibkr');
        }

        // continue

        // e.g get a contract
        const contract = await getContractDetails("AAPL");

        // Get portfolios
        const getPortfolios = await Portfolios.Instance.getPortfolios();

        // Add the backend service
        // ... e.g backendService();
    } catch (error) {
        console.log('error running app', error);
        process.exit(1);
    }
}

index();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants