Undefined variable, nodejs, json to program variable - javascript

I decided to save data the dirty way to a .json file. For some reason, when I run my index.js file which runs other modules I have written, it says that a particular variable I initialized in a separate module is undefined (one I was hoping to reference from json). The structure of my program is the standard index file that loads functions from modules I have written and executes them via endpoints.
.json File
{"blocks":[{"GENESIS_DATA":{"timestamp":1,"lastHash":"v01d","hash":"?M=(((Position-1)=>ter)=>sen)=>non?","difficulty":20,"nonce":0,"data":[]}}]}
I want to take the first index of this array named GENESIS_DATA and use it as an array in my program...
relevant code from blockchain index (not the file I execute for the program to run)
const { REWARD_INPUT, MINING_REWARD, GENESIS_DATA } = require('../config');
const fs = require('fs');
const jsonRoute = '/home/main/public_html/Cypher-Network/CDSM/CDSM.json';
class Blockchain {
constructor() {
fs.readFile(jsonRoute, 'utf-8', function(err, data) {
if (err) throw err;
this.jsonChain = JSON.parse(data);
const genesis = jsonChain.blocks[0];
});
this.chain = [genesis];
}
/*Alot more code down here but let's assume that the bracket for class Blockchain is completed*/
}
error log
/home/main/public_html/Cypher-Network/blockchain/index.js:32
this.chain = [genesis]; //we are taking the first element of the json file (genesis block)
^
ReferenceError: genesis is not defined
at new Blockchain (/home/main/public_html/Cypher-Network/blockchain/index.js:32:19)
at Object.<anonymous> (/home/main/public_html/Cypher-Network/index.js:28:20)
at Module._compile (internal/modules/cjs/loader.js:1158:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10)
at Module.load (internal/modules/cjs/loader.js:1002:32)
at Function.Module._load (internal/modules/cjs/loader.js:901:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)
at internal/main/run_main_module.js:18:47
main#goldengates.club [~/public_html/Cypher-Network]#

First, the constant genesis is local to the callback, so it is getting destroyed just after the callback has finished running.
Also even if the constant was declared outside the callback, remember that fs.readFile is asynchronous, so while readFile is reading the file containing the data, the constant genesis will have already been set to undefined.

Related

is there a problem with this expression {item_1.name: req.body.item } or alternatively with this {[item_1.name]: req.body.item }?

I'm trying to run this piece of code:
router.put('/restaurants/:id', async (req, res) => {
try {
const response = await Restaurant.findByIdAndUpdate(req.params.id, {name: req.body.name,
item_1.name: req.body.item,
item_2.name: req.body.item_2,
item_3.name: req.body.item_3,
item_4.name: req.body.item_4
})
res.send(response)
}
catch (error) {
res.send(error)
}
})
where the scenario is I have items (i.e item_1 etc) saved as objects in database, items got two properties name and rating, when admin wants to edit an item it should only be able to just edit the name property of an item not the rating, so for implementing this what i'm trying to do is, upon edit request as shown here, I want to set only the name property of an item as same to what has been sent in the request.
but it gives me a typescript error (though I don't have typescript installed) saying:
',' expected.ts(1005)
and it happens before running this code, actually vs code is showing this error.
and upon running it is showing something like this:
E:\xord\second_assignment\node\routes\restaurants.js:50
item_1.name: req.body.item,
^
SyntaxError: Unexpected token '.'
at wrapSafe (internal/modules/cjs/loader.js:1054:16)
at Module._compile (internal/modules/cjs/loader.js:1102:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
at Module.load (internal/modules/cjs/loader.js:986:32)
at Function.Module._load (internal/modules/cjs/loader.js:879:14)
at Module.require (internal/modules/cjs/loader.js:1026:19)
at require (internal/modules/cjs/helpers.js:72:18)
at Object.<anonymous> (E:\xord\second_assignment\node\index.js:8:21)
at Module._compile (internal/modules/cjs/loader.js:1138:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
at Module.load (internal/modules/cjs/loader.js:986:32)
at Function.Module._load (internal/modules/cjs/loader.js:879:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
[nodemon] app crashed - waiting for file changes before starting...
same thing happens with a different error when i try to access the object property with bracket notation.
I apologise for the very long query but I'm wondering; is the syntax I've used in this code for setting the value of an object's key inside another object, incorrect? if so then why? also what would be the alternative way to do this?
thanks God! in mongoose v5.10.19 documentation I saw almost the same instance where they use a property of an object as a key of another object here:
Parent.update({}, { 'child.name': 'Luke Skywalker' }, (error) => {
// Error because parentSchema has `strict: throw`, even though
// `childSchema` has `strict: false`
});
by which I learnt that in such cases one should wrap the key in quotes as they did in "child.name". and that resolved the issue i was facing.

Read Local CSV file into a 2D Array - Javascript

Hoping I could get some help with reading a csv file into a 2d array for a node app.
I've seen other questions with answers which suggest papaparse, jquery-csv, and csv npm packages. I have read the documentation for each of those solutions and do not see where in the process would my program read the csv.
I have a csv file in my documents folder: C:\Documents\Folder\data.csv for example.
I was hoping I could have the program read the data.csv which is formatted like so
header0 header1 header2 header3 header4 header5 header6 header7 header8 header9
data data data data data data data data data data
data data data data data data data data data data
and place it into an array called myarray
myarray[0][9] would give me header9 and so on.
Here is what I have when I tried jquery-csv
var fs = require('fs');
var csv = require('./jquery.csv.js');
var sample = 'C:\Documents\Folder\data.csv';
var myarray = $.csv.toArrays(sample);
The error I receive is
ReferenceError: $ is not defined
at Object.<anonymous> (C:\Users\0121160\Documents\Nodejs\readcsv.js:7:14)
[90m at Module._compile (internal/modules/cjs/loader.js:959:30)[39m
[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)[39m
[90m at Module.load (internal/modules/cjs/loader.js:815:32)[39m
[90m at Function.Module._load (internal/modules/cjs/loader.js:727:14)[39m
[90m at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)[39m
[90m at internal/main/run_main_module.js:17:11[39m
note: I have very minimal experience with javascript, node, jquery.
Any help would be greatly appreciated.
Thanks!
From https://www.npmjs.com/package/jquery ...
To include jQuery in Node, first install with npm.
npm install jquery
For jQuery to work in Node, a window with a document is required. Since no such window exists natively in Node, one can be mocked by tools such as jsdom. This can be useful for testing purposes.
require("jsdom").env("", function(err, window) {
if (err) {
console.error(err);
return;
}
var $ = require("jquery")(window);
});
The error says $ is not defined, so you need to use var myarray = csv.toArrays(sample);.
The variable $ does not mean anything to your program as you haven't imported anything that's assigned to the variable $.
I also doubt var csv = require('./jquery.csv.js'); will work, you'll probably have to npm install jquery-csv and then import var csv = require('jquery-csv') into your module.
jQuery is designed for helping do common things with JavaScript embedded on a webpage. jQuery CSV is a plugin for it.
Since you are writing software to run on Node.js and not in a webpage, jQuery isn't a great choice of library… so don't use it or a plugin for it.
Get a CSV parser optimised for Node.js such as csv-parser:
const fs = require('fs');
const csv = require('csv-parser')
const path = 'C:/Documents/Folder/data.csv';
const results = [];
fs.createReadStream(path)
.pipe(csv())
.on('data', (data) => results.push(data))
.on('end', () => {
console.log(results);
});

How to manage multiple .js files so as to run automated test cases using their tags in CucumberJS?

I am using CucumberJS with Selenium-Webdriver for automating my test cases. Currently I am having multiple feature files with their respective step-definition files. When I am trying to run the test cases then it is throwing an error:
Error: The previously configured ChromeDriver service is still
running. You must shut it down before you may adjust its
configuration.
at Object.setDefaultService (D:\code\egov-test-cases\node_modules\selenium-webdriver\chrome.js:305:11)
at new World (D:\code\egov-test-cases\features\support\world.js:21:12)
at Object. (D:\code\egov-test-cases\features\steps\create_approver_remittance_master.js:15:13)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Module.require (module.js:597:17)
at require (internal/module.js:11:18)
at supportCodePaths.forEach.codePath (D:\code\egov-test-cases\node_modules\cucumber\lib\cli\index.js:142:42)
at Array.forEach ()
at Cli.getSupportCodeLibrary (D:\code\egov-test-cases\node_modules\cucumber\lib\cli\index.js:142:22)
at D:\code\egov-test-cases\node_modules\cucumber\lib\cli\index.js:169:41
at Generator.next ()
at asyncGeneratorStep (D:\code\egov-test-cases\node_modules\cucumber\lib\cli\index.js:44:103)
error Command failed with exit code 1. info Visit
https://yarnpkg.com/en/docs/cli/run for documentation about this
command.
Since I am automating the tests, I have put the below code for automating chrome in world.js file, and then tried importing the driver from world.js, but still it is giving the same error.
class World {
constructor() {
const { setDefaultTimeout } = require('cucumber');
const webdriver = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const path = require('chromedriver').path;
const screen = {
width: 640,
height: 480
};
setDefaultTimeout(100 * 5000);
var service = new chrome.ServiceBuilder(path).build();
chrome.setDefaultService(service);
this.driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
}
}
What you may need to do is kill your browser after each test run as the containers are reused(hence why a browser may already be running). To do this you will want to add a hooks file to your support folder and include something as follows
After({}, async function(scenario) {
this.driver.quit();
}
});
for more info take a look at the docs https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/hooks.md
I found the solution to my problem. Actually the driver was getting initialized multiple times and that is why it was giving me the above error. I was creating the driver inside the constructor in the class World in world.js file. Everytime i was taking an instance of the class World, I was creating a new driver. I shifted the driver declaration outside the class as const driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build() and created a method as initialize() { return driver; } in world.js file. I am calling the initialize() method in my step definition files as let world = new World(); let driver = world.initialize(). Now I am good to go!

Smart contract method is not a function in web3

I am trying to follow an older tutorial on web3, but am getting errors that I believe are due Solidity being updated. I have the following code shown below
var express = require("express"),
Web3 = require("web3"),
web3;
if (typeof web3 !== 'undefined') {
web3 = new Web3(web3.currentProvider);
} else {
// set the provider you want from Web3.providers
web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
}
web3.eth.defaultAccount = web3.eth.accounts[0];
//define contract variable using ABI from compiled Remix tab.
var myContract = new web3.eth.Contract([abi_data]);
myContract.options.address = 'contract_address';
myContract.methods.totalSupply(function(err,res){
if(!err){
console.log(res);
} else {
console.log(err);
}
})
where abi_data is my contract's abi data, contract_address is my contract's actual address in the Roptsen test network, and where totalSupply() is the method in my solidity smart contract on the Ropsten test network that returns the total supply of the token referenced in the contract. When testing this with node app.js to see if this logs properly, this error is returned...
/home/ubuntu/workspace/node_modules/web3-eth-contract/src/index.js:693
throw errors.InvalidNumberOfParams(args.length, this.method.inputs.length, this.method.name);
^
Error: Invalid number of parameters for "totalSupply". Got 1 expected 0!
at Object.InvalidNumberOfParams (/home/ubuntu/workspace/node_modules/web3-core-helpers/src/errors.js:32:16)
at Object._createTxObject (/home/ubuntu/workspace/node_modules/web3-eth-contract/src/index.js:693:22)
at Object.<anonymous> (/home/ubuntu/workspace/client/app.js:290:25)
at Module._compile (module.js:570:32)
at Object.Module._extensions..js (module.js:579:10)
at Module.load (module.js:487:32)
at tryModuleLoad (module.js:446:12)
at Function.Module._load (module.js:438:3)
at Module.runMain (module.js:604:10)
at run (bootstrap_node.js:389:7)
at startup (bootstrap_node.js:149:9)
And totalSupply is defined in Soldiity as follows...
function totalSupply() constant returns (uint256 totalSupply){
return _totalSupply;
}
Using Adam's fix, I still get the following error...
Error: Invalid JSON RPC response: ""
at Object.InvalidResponse (/home/ubuntu/workspace/node_modules/web3-core-helpers/src/errors.js:42:16)
at XMLHttpRequest.request.onreadystatechange (/home/ubuntu/workspace/node_modules/web3-providers-http/src/index.js:73:32)
at XMLHttpRequestEventTarget.dispatchEvent (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:64:18)
at XMLHttpRequest._setReadyState (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:354:12)
at XMLHttpRequest._onHttpRequestError (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:544:12)
at ClientRequest.<anonymous> (/home/ubuntu/workspace/node_modules/xhr2/lib/xhr2.js:414:24)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at Socket.socketErrorListener (_http_client.js:310:9)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at emitErrorNT (net.js:1277:8)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickCallback (internal/process/next_tick.js:104:9)
Take a closer look at the web3 1.0 documentation for calling methods (it's very different from the 0.2x API). To call a contract method, you need to first create the method object using contractInstance.methods.methodName() replacing "methodName" with the method in the contract you want to call. You also need to pass in the parameters for the contract function to this method (the callback does not get passed in here). With the method object, you can then use either the call method (for constant functions) or send (for transactions). totalSupply should be a constant function, so your code should be:
myContract.methods.totalSupply().call(function(err,res){
if(!err){
console.log(res);
} else {
console.log(err);
}
);
Or you can use the returned Promise instead of passing in the callback:
myContract.methods.totalSupply().call().then(function(res){
console.log(res);
}).catch(function(err) {
console.log(err);
});
Sending transactions is similar, but uses an event emitter for receiving the transaction hash, receipt, etc.
For anyone else struggling, try to check whether your ABI json actually includes the method you are trying to call. It could have been that you copied the ABI for the wrong contract as Remix would by default list the first contract in the default template rather than your newly created contract.
This is a new language for me so my error came when I copied the abi into my variable and it pasted an extra set of "[]" so it looked something like:
const abi = [[...]];
If I'm correct, it should be:
const abi = [...];
with only single set of the most outer square brackets. This is probably only a mistake for someone like myself who is still learning the syntax of this language.
There is actually a simple fix to this:
I was using express and web3 together but web3 1.0.0-beta was the issue. You just have to install a stable version such as 0.19.0 or 0.20.0
npm install web3#^0.19.0 --save
Then it will work.

NodeJs : TypeError: require(...) is not a function

I am trying to require a file and afterwards pass it to a var. I am following this tutorial to create an authentication system. After writing the server.js file and trying to compile I got a BSON error therefore I changed the line that required the release version of it in mongoose.
Here are my code and error:
server.js
require('./app/routes')(app, passport);
Error
require('./app/routes')(app, passport);
^
TypeError: require(...) is not a function
at Object.<anonymous> (d:\Node JS learning\WorkWarV2\server.js:38:24)
at Module._compile (module.js:434:26)
at Object.Module._extensions..js (module.js:452:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:475:10)
at startup (node.js:117:18)
at node.js:951:3
Process finished with exit code 1
I have read that this usually means that requireJS is not getting loaded properly yet I am not aware why or how to fix it.
Edit due to comment:
As asked, here is the result of console.log(require);
For me, when I do Immediately invoked function, I need to put ; at the end of require().
Error:
const fs = require('fs')
(() => {
console.log('wow')
})()
Good:
const fs = require('fs');
(() => {
console.log('wow')
})()
I think this means that module.exports in your ./app/routes module is not assigned to be a function so therefore require('./app/routes') does not resolve to a function so therefore, you cannot call it as a function like this require('./app/routes')(app, passport).
Show us ./app/routes if you want us to comment further on that.
It should look something like this;
module.exports = function(app, passport) {
// code here
}
You are exporting a function that can then be called like require('./app/routes')(app, passport).
One other reason a similar error could occur is if you have a circular module dependency where module A is trying to require(B) and module B is trying to require(A). When this happens, it will be detected by the require() sub-system and one of them will come back as null and thus trying to call that as a function will not work. The fix in that case is to remove the circular dependency, usually by breaking common code into a third module that both can separately load though the specifics of fixing a circular dependency are unique for each situation.
For me, this was an issue with cyclic dependencies.
IOW, module A required module B, and module B required module A.
So in module B, require('./A') is an empty object rather than a function.
How to deal with cyclic dependencies in Node.js
Remember to export your routes.js.
In routes.js, write your routes and all your code in this function module:
exports = function(app, passport) {
/* write here your code */
}
For me, I got similar error when switched between branches - one used newer ("typescriptish") version of #google-cloud/datastore packages which returns object with Datastore constructor as one of properties of exported object and I switched to other branch for a task, an older datastore version was used there, which exports Datastore constructor "directly" as module.exports value. I got the error because node_modules still had newer modules used by branch I switched from.
I've faced to something like this too.
in your routes file , export the function as an object like this :
module.exports = {
hbd: handlebar
}
and in your app file , you can have access to the function by .hbd
and there is no ptoblem ....!
I don't know how but in may case it got fixed when I changed
require('./routes')(app)
to
require('./routes')
In my case i fix when i put the S in the module.exportS,
BEFORE:
module.export = () => {}
AFTER:
module.exports = () => {}

Categories

Resources