Nodejs doesnt recognize async function and reference - node.js

When i run my project in terminal like this
node index.js
I get a reference error: config not defined
/home/ether/Documents/nodesendeth/index.js:6
const {asset, base, spread, allocation} = config;
^
ReferenceError: config is not defined
at tick (/home/ether/Documents/nodesendeth/index.js:6:47)
at run (/home/ether/Documents/nodesendeth/index.js:49:3)
at Object.<anonymous> (/home/ether/Documents/nodesendeth/index.js:52:1)
at Module._compile (internal/modules/cjs/loader.js:1151:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1171:10)
at Module.load (internal/modules/cjs/loader.js:1000:32)
at Function.Module._load (internal/modules/cjs/loader.js:899:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
in my code i have assigned the config constant like this:
require('dotenv').config;
const ccxt = require('ccxt');
const axios = require('axios');
const tick = async => {
const {asset, base, spread, allocation} = config;
const market = `${asset}/${base}`;
const orders = binanceClient.fetchOpenOrders(market);
orders.forEach(async order => {
await binanceClient.cancelOrder(order.id);
});
const results = Promise.all([
axios.get('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd'),
axios.get('https://api.coingecko.com/api/v3/simple/price?ids=tether&vs_currencies=usd')
]);
const marketPrice = results[0].data.bitcoin.usd / results[1].data.tether.usd;
const sellPrice = marketPrice * (1 + spread);
const buyPrice = marketPrice * (1 - spread);
const balances = binanceClient.fetchBalance();
const assetBalance = balances.free[asset];
const baseBalance = balances.free[base];
const sellVolume = assetBalance * allocation;
const buyVolume = (baseBalance * allocation) / marketPrice;
binanceClient.createLimitSellOrder(market, sellVolume, sellPrice);
binanceClient.createLimitBuyOrder(market, sellVolume, buyPrice);
console.log(`
New tick for ${market}...
Created limit sell order for ${sellVolume}#${sellPrice}
Create limit buy order for ${buyVolume}#${buyPrice}`)
}
const run = () => {
const config = {
asset: 'BTC',
base: 'USDT',
allocation: 0.1,
spread: 0.2,
tickInterval: 2000
};
const binanceClient = new ccxt.binance({
apiKey: process.env.API_ENV,
secret: process.env.API_SECRET,
});
tick(config, binanceClient);
setInterval(tick, config.tickInterval, config, binanceClient);
}
run()
I also got await errors saying that i need to run them in an sync function which I do.
i have removed the await keyword now but the app should run with the await kewyword because those functions are async.
Why am i getting those errors when i have a config variable aswell as an async function?
I assume that something with my async function doesnt work because it neither recognises the config constant nor the async/await calls

config is undefined in your code.
You likely meant to declare it on this line, as follows:
const config = require('dotenv').config();
...but this is only half of your problem because, furthermore, the object returned by .config() puts all the variables in a parsed property.
So for example, if your .env looked like this:
apple=red
ball=blue
...and you just logged config, you'd see this:
{ parsed: { apple: 'red', ball: 'blue' } }
Then you could write:
const {apple, ball} = require('dotenv').config().parsed;
console.log(apple, ball);
And this would write:
red blue
In your specific case, if you are expecting asset, base, spread, and allocation to be environment variables in your .env file, then you could potentially change the line to say:
const {asset, base, spread, allocation} = config.parsed;

Related

Node.js - Function not working when exported

Good day everyone,
First off, thanks for always being such an amazing community. You all really are helping me a ton with learning and bettering my programming and development!
I have a small question related to the module.exports within Node.js. The function below runs with no issues when called on directly:
const fs = require('fs')
const {nanoid} = require('nanoid')
const createStormDB = () => {
return new Promise((resolve, reject) => {
try{
const id = nanoid(4)
const date = new Date() // Create date string for file naming
let dateString = `${date.toISOString().split('T')[0]}` // Create date string for file naming
let fileName = `${dateString}_deals_${id}.stormdb` // Create date string for file naming
fs.openSync(`../StormDB/${fileName}`, 'w')
resolve(fileName)
}catch(err){
reject(err)
}
})
}
module.exports = createStormDB
It creates a file with a specific name within in specific folder. But when I use module.exports = createStormDB I am greeted with the following error:
(node:12516) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '../StormDB/2021-07-19_deals_gYmJ.stormdb'
at Object.openSync (fs.js:476:3)
at C:\Node\Pipedrive-Connector\PipeDriveRequest\scripts\createStormDBFile.js:11:16
at new Promise (<anonymous>)
at createStormDB (C:\Node\Pipedrive-Connector\PipeDriveRequest\scripts\createStormDBFile.js:5:12)
at Object.<anonymous> (C:\Node\Pipedrive-Connector\PipeDriveRequest\play.js:7:1)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
Is there something I am misunderstanding when it comes to exporting modules? I'm importing this module using the require option! Thanks so much for the help!
The .. relative path in the function is relative to the calling scripts current working directory, not the directory the file is in.
Assuming from your path setup and description the database is in: C:\Node\Pipedrive-Connector\PipeDriveRequest\StormDB
If you want the database path to remain relative to the javascript file containing the function, use __dirname
const path = require('path')
const db_path = path.join(__dirname, '..', 'StormDB', filename)
fs.openSync(db_path, 'w')

How to suppress Jest Linter errors from import files?

So I'm trying to do some basic API testing with Jest by importing a function from handler.ts but Jest crawls through the handler ts imports and gives me linter errors for a file that handler importest from my libs folder when all I want to do is check if the result of that function equals what I want it to equal.
Here's my test file test/handler.test.ts:
import { getInbox } from './../handler'
import * as myMongo from '../../../libs/mongo';
import { Db } from 'mongodb';
const productionDbPromise: Promise<Db> = myMongo.getProductionDb();
test("Case page 1, limit 5", async ()=>{
const page = 1;
const limit = 5;
const event = {
queryStringParameters: {
page: page,
limit: limit
}
};
const productionDb = await productionDbPromise;
const seekerCollection = productionDb.collection('seekers');
const totalDocs = await seekerCollection.countDocuments({ lastMessageDate: { $ne: null } });
const code = 200;
const status = 'OK';
const res: any = await getInbox(event);
expect(res.code).toEqual(code);
expect(res.status).toEqual(status);
expect(res.json().totalDocs).toEqual(totalDocs);
expect(res.json().seekers.length).toEqual(limit);
});
And here's the error:
Test suite failed to run
TypeError: twilio is not a function
6 | export const client = twilio(accountSid, authToken);
7 | export const messagingServiceSid = process.env.TWILIO_SERVICE_ID;
> 8 |
| ^
at Object.<anonymous> (../../libs/twilio.ts:8:18)
at Object.<anonymous> (../../libs/message.ts:7:18)
at Object.<anonymous> (handler.ts:14:19)
at Object.<anonymous> (__test__/handler.test.ts:4:19)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 12.086 s
npm ERR! Test failed. See above for more details.
Any idea how to get it to ignore this? (which by the way the function I'm testing does not even use any exports from that libs file, and the twilio object is correctly imported on the first line of that file)
It's not Jest's responsibility to run a linter, also it doesn't crawl through any modules that weren't explicitly imported.
This is not linter but runtime error, and it cannot be suppressed or discarded. The problem is exactly what it says:
TypeError: twilio is not a function
Call stack gives a good idea where it comes from:
at Object.<anonymous> (../../libs/twilio.ts:8:18)
at Object.<anonymous> (../../libs/message.ts:7:18)
at Object.<anonymous> (handler.ts:14:19)
at Object.<anonymous> (__test__/handler.test.ts:4:19)
handler.ts depends on message.ts, and message.ts depends on twilio.ts, where the error happens. If twilio is not supposed to be available in tests, either it or one of these modules need to be mocked.

Function is not defined error in nodejs. What's wrong with my code?

I created two files, app.js and helpers.js and when I tried to call a function from app.js, I got an error, function is not defined.
The two files are located in the same folder. I think there is a problem the module.exports keyword,
can anyone help me here? Here is the code of the two separate files:
//app.js
const helpers= require('./helpers');
const total= sum(10,20);
console.log("total:",total);
//helpers.js
const sum = (a,b)=>{
return a+b;
}
module.exports={
sum
};
And the error i am getting is:
const total= sum(10,20);
^
ReferenceError: sum is not defined
at Object.<anonymous> (E:\testing\app.js:5:14)
at Module._compile (internal/modules/cjs/loader.js:1147:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1167:10)
at Module.load (internal/modules/cjs/loader.js:996:32)
at Function.Module._load (internal/modules/cjs/loader.js:896:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
Try this way:
//app.js
const helpers= require('./helpers');
const total= helpers.sum(10,20);
console.log("total:",total);
//helpers.js
const sum = (a,b)=> {
return a+b;
}
module.exports = sum;
The problem is that you are exporting your function sum in helpers.js within an object:
// helpers.js
// ...
module.exports = {
sum
};
If you want to access it from app.js you can either use helpers.sum(...) to access it:
// app.js
const helpers = require('./helpers');
const total = helpers.sum(10, 20);
console.log("total:", total);
... or you can use object deconstruction in the require line:
// app.js
const { sum } = require('./helpers');
// ...
Update
Sure, the answer you posted does work, but from the name helpers.js I assume that you might want to put multiple helper functions into that file. Then, you must use an object export - as mentioned above - in order to export all helper functions.
You can try to edit the way to export the sum function to:
module.exports = sum;
That's because when you define:
module.exports = {...}
it means you're exporting an object, not a function.
Usage:
const sum= require('./helpers');
const total= sum(10,20);
console.log("total:",total);
Finally, I found a my answer.
I just needed to replace the helpers keyword with sum keyword in the first line of app.js and I also removed the curly braces around sum in helpers.js as per other's advice.
The correct code is below
//app.js
const sum= require('./helpers');
const total= sum(10,20);
console.log("total:",total);
and
//helpers.js
const sum = (a,b)=>{
return a+b;
}
module.exports=sum;

Smart contract deployment with node is not working

I have a problem like this. I am new to blockchain development and I have created a Smart contract using solidity. To compile it and to deploy it I have created a compile.js and deploy.js file.
This is my Solidity file.
pragma solidity 0.4.20;
contract Election {
// Model a Candidate
struct Candidate {
uint id;
string name;
uint voteCount;
}
// Store accounts that have voted
mapping(address => bool) public voters;
// Store Candidates
// Fetch Candidate
mapping(uint => Candidate) public candidates;
// Store Candidates Count
uint public candidatesCount;
// voted event
event votedEvent (
uint indexed _candidateId
);
function Election () public {
addCandidate("Candidate 1");
addCandidate("Candidate 2");
}
function addCandidate (string _name) private {
candidatesCount ++;
candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
}
function vote (uint _candidateId) public {
// require that they haven't voted before
require(!voters[msg.sender]);
// require a valid candidate
require(_candidateId > 0 && _candidateId <= candidatesCount);
// record that voter has voted
voters[msg.sender] = true;
// update candidate vote Count
candidates[_candidateId].voteCount ++;
// trigger voted event
votedEvent(_candidateId);
}
}
This is my compile.js file.
const path = require('path');
const fs =require('fs');
const solc = require('solc');
const electionPath= path.resolve(__dirname,'contracts','Election.sol');
const source = fs.readFileSync(electionPath,'utf8');
module.exports = solc.compile(source,1).contracts[':Election'];
This is my deploy.js file.
const HDWalletProvider = require('truffle-hdwallet-provider');
const Web3 = require('web3');
const { interface , bytecode } = require('./compile');
const provider = new HDWalletProvider(
'retire embark gravity flight also ceiling dinr wine example slender armor rate',
'https://rinkeby.infura.io/v3/mykey'
);
const web3 = new Web3(provider);
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
console.log('Attempting to deploy from account',accounts[0]);
const result = await new web3.eth.Contract(JSON.parse(interface))
.deploy({data:bytecode})
.send({gas:'1000000',from :accounts[0]});
console.log( interface );
console.log( 'contract deploy to', result.options.address);
};
deploy();
When I hit node deploy.js in the command prompt it gives me an error like this.
TypeError: Cannot destructure property `interface` of 'undefined' or 'null'.
at Object.<anonymous> (C:\Users\tharindusa\Desktop\election\deploy.js:3:34)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
Can someone help me to solve this problem? I search a lot but I was unable to find a suitable solution for this. Thank you.
I got the same error. I used solc.compile(source, 1).errors as Adam suggested and found a typo in the contract. You should try that.

Firebase Cloud Function - Unit Testing - Please supply a Firebase app in the constructor for DataSnapshot in order to use the .ref method

I am trying to setup Unit Testing for Firebase cloud functions. I was following these links:
https://firebase.google.com/docs/functions/unit-testing
https://github.com/firebase/functions-samples/blob/4663b4ddfae3ed8f8a110156d60e71f028680ee7/quickstarts/uppercase/functions/test/test.online.js
I am trying to make the sample code run. Code is as follows:
const chai = require('chai');
const sinon = require('sinon');
const admin = require('firebase-admin');
const projectConfig = {
databaseURL : 'https://gr-automation-5e65c.firebaseio.com',
storageBucket : 'gr-automation-5e65c.appspot.com',
projectId : 'gr-automation-5e65c',
};
const test = require('firebase-functions-test')(projectConfig, '../gr-automation-5e65c-firebase-adminsdk-jkdtf-849f3d0f65.json');
test.mockConfig( /* removed for Clarity */ );
const assert = chai.assert;
describe('Cloud Functions', () => {
let myFunctions;
adminInitStub = sinon.stub(admin, 'initializeApp');
admin.initializeApp();
//console.log(test);
before(() => {
myFunctions = require('../lib/index.js');
//console.log(myFunctions);
//console.log(admin);
});
after(() => {
test.cleanup();
admin.database().ref('messages').remove();
});
describe('makeUpperCase', () => {
it('should upper case input and write it to /uppercase', () => {
const snap = test.database.makeDataSnapshot('input', 'messages/11111/original');
const wrapped = test.wrap(myFunctions.makeUppercase);
return wrapped(snap).then(() => {
return admin.database().ref('messages/11111/uppercase').once('value').then((createdSnap) => {
assert.equal(createdSnap.val(), 'INPUT');
});
});
})
});
});
When I run the test, I get the following error:
Cloud Functions
makeUpperCase
Uppercasing undefined input
1) should upper case input and write it to /uppercase
2) "after all" hook
0 passing (364ms)
2 failing
1) Cloud Functions
makeUpperCase
should upper case input and write it to /uppercase:
Error: Please supply a Firebase app in the constructor for DataSnapshot in order to use the .ref method.
at DataSnapshot.get ref [as ref] (node_modules/firebase-functions/lib/providers/database.js:186:19)
at Function.exports.makeUppercase.functions.database.ref.onCreate [as run] (lib/index.js:135:21)
at wrapped (node_modules/firebase-functions-test/lib/main.js:53:30)
at Context.it (test/index.test.js:46:13)
2) Cloud Functions
"after all" hook:
Error: The default Firebase app does not exist. Make sure you call initializeApp() before using any of the Firebase services.
at FirebaseAppError.FirebaseError [as constructor] (node_modules/firebase-admin/lib/utils/error.js:39:28)
at FirebaseAppError.PrefixedFirebaseError [as constructor] (node_modules/firebase-admin/lib/utils/error.js:85:28)
at new FirebaseAppError (node_modules/firebase-admin/lib/utils/error.js:119:28)
at FirebaseNamespaceInternals.app (node_modules/firebase-admin/lib/firebase-namespace.js:105:19)
at FirebaseNamespace.app (node_modules/firebase-admin/lib/firebase-namespace.js:372:30)
at FirebaseNamespace.ensureApp (node_modules/firebase-admin/lib/firebase-namespace.js:388:24)
at FirebaseNamespace.fn (node_modules/firebase-admin/lib/firebase-namespace.js:283:30)
at Context.after (test/index.test.js:31:15)
Any hint on what am I doing wrong?
test.data.makeDataSnapshot has an optional third parameter which is a Firebase app (see https://firebase.google.com/docs/reference/functions/test/test.database#.makeDataSnapshot). However, since you initialized the firebase-functions-test with your project config values, you normally do not need to supply it.
However you have this line:
adminInitStub = sinon.stub(admin, 'initializeApp');
This is causing the next line to initialize a fake app, since initializeApp method was stubbed out to not do anything
This is causing the 2 failures, to fix, remove:
adminInitStub = sinon.stub(admin, 'initializeApp');

Resources