use node-redis with node 8 util.promisify - node.js

node -v : 8.1.2
I use redis client node_redis with node 8 util.promisify , no blurbird.
the callback redis.get is ok, but promisify type get error message
TypeError: Cannot read property 'internal_send_command' of undefined
at get (D:\Github\redis-test\node_modules\redis\lib\commands.js:62:24)
at get (internal/util.js:229:26)
at D:\Github\redis-test\app.js:23:27
at Object. (D:\Github\redis-test\app.js:31:3)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Function.Module.runMain (module.js:605:10)
my test code
const util = require('util');
var redis = require("redis"),
client = redis.createClient({
host: "192.168.99.100",
port: 32768,
});
let get = util.promisify(client.get);
(async function () {
client.set(["aaa", JSON.stringify({
A: 'a',
B: 'b',
C: "C"
})]);
client.get("aaa", (err, value) => {
console.log(`use callback: ${value}`);
});
try {
let value = await get("aaa");
console.log(`use promisify: ${value}`);
} catch (e) {
console.log(`promisify error:`);
console.log(e);
}
client.quit();
})()

changing let get = util.promisify(client.get);
to let get = util.promisify(client.get).bind(client);
solved it for me :)

If you are using node v8 or higher, you can promisify node_redis with
util.promisify as in:
const {promisify} = require('util');
const getAsync = promisify(client.get).bind(client); // now getAsync is a promisified version of client.get:
// We expect a value 'foo': 'bar' to be present
// So instead of writing client.get('foo', cb); you have to write:
return getAsync('foo').then(function(res) {
console.log(res); // => 'bar'
});
or using async await:
async myFunc() {
const res = await getAsync('foo');
console.log(res);
}
culled shamelessly from redis official repo

You can also use Blue Bird Library plus monkey patching will do the trick for you.
For example:
const bluebird = require('bluebird')
const redis = require('redis')
async connectToRedis() {
// use your url to connect to redis
const url = '//localhost:6379'
const client = await redis.createClient({
url: this.url
})
client.get = bluebird.promisify(client.get).bind(client);
return client
}
// To connect to redis server and getting the key from redis
connectToRedis().then(client => client.get(/* Your Key */)).then(console.log)

Related

What is the Unexpected Token syntax error in line six?

I'm trying to learn how to create NFTs on the Ethereum block chain.
In terminal (Ubuntu 20.04.3 LTS)
Aki-Zeta:~/my-nft$ node scripts/mint-nft.js
I keep getting
/home/patonn89/my-nft/scripts/mint-nft.js:6
const { createAlchemyWeb3 }
^
Syntax Error Unexpected Token {
see bottom for full error
Here is my code using VScode
require("dotenv").config()
const API_URL = process.env.API_URL;
const PUBLIC_KEY = process.env.PUBLIC_KEY;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const { createAlchemyWeb3 } = require("#alch/alchemy-web3")
const web3 = createAlchemyWeb3(API_URL)
const contract = require("../artifacts/contracts/MyNFT.sol/MyNFT.json")
const contractAddress = "0xf469355dc12e00d8cda65b3a465bdad65da27e22"
const nftContract = new web3.eth.Contract(contract.abi, contractAddress)
async function mintNFT(tokenURI) {
const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest'); //get latest nonce
//the transaction
const tx = {
'from': PUBLIC_KEY,
'to': contractAddress,
'nonce': nonce,
'gas': 500000,
'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI(),
}
const signPromise = web3.eth.accounts.signTransaction(tx, PRIVATE_KEY)
signPromise
.then((signedTx) => {
web3.eth.sendSignedTransaction(
signedTx.rawTransaction,
function (err, hash) {
if (!err) {
console.log(
"The hash of your transaction is: ",
hash,
"\nCheck Alchemy's Mempool to view the status of your transaction!"
)
} else {
console.log(
"Something went wrong when submitting your transaction:",
err
)
}
}
)
})
.catch((err) => {
console.log(" Promise failed:", err)
})
}​
mintNFT(
"https://gateway.pinata.cloud/ipfs/QmcRikKfA6xdaNZkojW28xpvZYysQXSJEb52YdeRJP3GGv"
)
Is it something to do with that "{" in line 6, or something else in line 6?
Prior to running this script I ran "npm install #alch/alchemy-web3", and verified the directories exist (both by going there and with cd). Other people with similar issues are missing something, and I have no idea what I'm missing. I have checked for spurious spaces and semicolons but I am not experienced with this language.
I have been using the tutorials off of the Ethereum project site.
full error
/home/patonn89/my-nft/scripts/mint-nft.js:6
const { createAlchemyWeb3 }
^
SyntaxError: Unexpected token {
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:413:25)
at Object.Module._extensions..js (module.js:448:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:471:10)
at startup (node.js:117:18)
at node.js:951:3
I had exactly the same error, and it was just a spurious character in my VScode editor, same example as you from ethereum.org.
As you can see in line 24
change const { createAlchemyWeb3 } to const { createAlchemyWeb3 } = require("#alch/alchemy-web3")

While I was trying to connect Mondo DB, event.bind stopped working as a function

I've got all the packages necessary and whatnot but I keep on getting an error. First of all, here's my coding (in a file called main.js.):
const client = new Discord.Client();
require("dotenv").config();
const fs = require('fs');
const mongoose = require('mongoose');
client.commands = new Discord.Collection();
client.events = new Discord.Collection();
["command_handler", "event_handler"].forEach((handler) => {
require(`./handlers/${handler}`)(client, Discord);
});
mongoose
.connect(process.env.MONGODB_SRV, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
})
.then(()=>{
console.log('Connected to the database!');
})
.catch((err) => {
console.log(err);
});
client.login(process.env.DISCORD_TOKEN);
My error is
C:\Users\shann\Desktop\DiscordBot\handlers\event_handler.js:10
client.on(event_name, event.bind(null, Discord, client));
^
TypeError: event.bind is not a function
at load_dir (C:\Users\shann\Desktop\DiscordBot\handlers\event_handler.js:10:41)
at C:\Users\shann\Desktop\DiscordBot\handlers\event_handler.js:14:38
at Array.forEach (<anonymous>)
at module.exports (C:\Users\shann\Desktop\DiscordBot\handlers\event_handler.js:14:25)
at C:\Users\shann\Desktop\DiscordBot\main.js:11:37
at Array.forEach (<anonymous>)
at Object.<anonymous> (C:\Users\shann\Desktop\DiscordBot\main.js:10:38)
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)
at internal/main/run_main_module.js:17:47
I honestly don't know what the problem is this time. Should I define event.bind? I thought .bind was a function and event was the variable. I've been following a tutorial. I do have mongoose installed through the command center but I don't know if I should reinstall it. Also, I don't see any errors in my coding but I am pretty new so please point them out and how I can fix it!
The coding for command_handler.js
const fs = require('fs');
module.exports = (client, Discord)=>{
const command_files = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for(const file of command_files){
const command = require(`../commands/${file}`)
if(command.name){
client.commands.set(command.name, command);
} else {
continue;
}
}
}
The coding for event_handler.js is
const fs = require('fs');
module.exports = (client, Discord)=>{
const load_dir = (dirs)=>{
const event_files = fs.readdirSync(`./events/${dirs}`).filter(file => file.endsWith('.js'));
for(const file of event_files){
const event = require(`../events/${dirs}/${file}`);
const event_name = file.split('.')[0];
client.on(event_name, event.bind(null, Discord, client));
}
}
['client', 'guild'].forEach(e => load_dir(e));
}
There isn't actually much of an answer here but the thing is, you don't even need an advanced event handler. All I did was remove the event handler from my handlers and added an event handler to my main.js. Then I removed client and guild from my events. After that, I made it so that in main.js it would look at all the files in events (the folder with all my events) and run them (using fs)!
Credits to #WorthyAlpaca for the help in introducing this alternate method

NodeJs await is only valid in async function [duplicate]

This question already has answers here:
await is only valid in async function
(14 answers)
How to resolve the Syntax error : await is only valid in async function?
(2 answers)
Closed 2 years ago.
I am trying to set some data in firestore using this node js code :
const db = admin.firestore();
const allDB = db.collection("like").doc("all").collection("movies");
const s1 = db.collection("like").doc("all");
await s1.set({
type: ["all"],
});
running the file in console : node file.js
Gives me this error :
await s1.set({
^^^^^
SyntaxError: await is only valid in async function
at wrapSafe (internal/modules/cjs/loader.js:1053:16)
at Module._compile (internal/modules/cjs/loader.js:1101:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
at Module.load (internal/modules/cjs/loader.js:985:32)
at Function.Module._load (internal/modules/cjs/loader.js:878:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
How to solve this issue
Wrap your code in async function
async function run(){
const db = admin.firestore();
const allDB = db.collection("like").doc("all").collection("movies");
const s1 = db.collection("like").doc("all");
await s1.set({
type: ["all"],
});
}
run().catch(e => { console.error(e); process.exit(-1); })
You should use it inside an async function, this will work:
const doSomething = async () => {
const db = admin.firestore();
const allDB = db.collection("like").doc("all").collection("movies");
const s1 = db.collection("like").doc("all");
await s1.set({
type: ["all"],
});
}
like in the answer above, you just need to make an async function by using the async title thing, then naming a function with the stuff inside it

Node: SerialPort is not a constructor

I'm trying to connect to my Raspberry pi's serialport via node but when i run the js file it comes up with this error:
var serialport = new SerialPort("/dev/ttyAMA0", {
^
TypeError: SerialPort is not a constructor
at Object.<anonymous> (/home/pi/exploringrpi/chp13/xbee/nodejs/test.js:12:18)
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
node is at version 8.11.4
serialport is at version 7.0.2
This is the code:
// From the example code at www.npmjs.com/package/xbee-api
var util = require('util');
var SerialPort = require('serialport').SerialPort;
var xbee_api = require('xbee-api');
var C = xbee_api.constants;
var xbeeAPI = new xbee_api.XBeeAPI({
api_mode: 1
});
var serialport = new SerialPort("/dev/ttyAMA0", {
baudRate: 115200});
serialport.on("open", function() {
var frame_obj = { // AT Request to be sent to
type: C.FRAME_TYPE.AT_COMMAND, // Prepare for an AT command
command: "NI", // Node identifer command
commandParameter: [], // No parameters needed
};
serialport.write(xbeeAPI.buildFrame(frame_obj));
});
// The data frames are outputted by this function
xbeeAPI.on("frame_object", function(frame) {
console.log(">>", frame);
});
Hope you can help
You should probably remove the .SerialPort at the end of the require line:
var SerialPort = require('serialport').SerialPort;
The serial port documentation shows how it should be used, and it doesn't include that .SerialPort at the end:
var SerialPort = require('serialport');
var port = new SerialPort('/dev/ttyAMA0', {
baudRate: /dev/ttyAMA0
});
Another error was shown to me:
throw new TypeError("path" is not defined: ${settings.path});
I created the port object like this:
const sp = new SerialPort("/dev/ttyACM0", {baudRate: 4800});
It was wrong way.
Try to create port and define the path inside curl brackets:
const sp = new SerialPort({path: "/dev/ttyACM0", baudRate: 4800});
const SerialPort = require('serialport').SerialPort;
const sp = new SerialPort({path: "/dev/ttyACM0", baudRate: 4800});
const sent_data = '\x45';
sp.on("open", function() {
console.log("port has opened");
sp.write(sent_data, function(err){
if(err){
return console.log('Error on write', err.message);
}
console.log('Port.write: ', sent_data);
});
});
sp.on('data', function(data){
// decoding uint8Array to string
var enc = new TextDecoder();
var arr = new Uint8Array(data);
ready = enc.decode(arr)
console.log('Data received: ', ready);
});
// Read data that is available but keep the stream from entering "flowing mode"
sp.on('readable', function () {
console.log('Data2:', sp.read());
});

"Learning Node JS" example - 'The super constructor to "inherits" must not ' +'

I'm fowolling along to exercise in the O'Reilly "Learning Node JS" book and I've run into an unrunnable example. My code is as follows:
"use strict";
var util = require('util');
var eventEmitter = require('events').eventEmitter;
var fs = require('fs')
function InputChecker(name, file) {
this.name = name;
this.writeStream = fs.createWriteStream('./' + file + '.txt',
{'flags': 'a',
'encoding': 'utf8',
'mode' : 0o666});
};
util.inherits(InputChecker, eventEmitter);
InputChecker.prototype.check = function check(input) {
let command = input.trim().substr(0,3);
if (command == 'wr') {
this.emit('write', input.substr(3, input.length));
} else if (command == 'en:') {
this.emit('end');
} else {
this.emit('echo', input);
}
};
let ic = new InputChecker('Shelley', 'output');
ic.on('write', function(data) {
this.writeStream.write(data, 'utf8');
});
ic.on('echo', function(data) {
process.stdout.write(ict.name + ' wrote ' + data);
});
ic.on('end', function() {
process.exit();
});
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function() {
let input = process.stdin.read();
if (input != null)
ic.check(input);
});
The error is:
[user#MacBook-Pro NodeJS]$ node fileevent.js
util.js:957
throw new TypeError('The super constructor to "inherits" must not ' +
^
TypeError: The super constructor to "inherits" must not be null or undefined
at Object.exports.inherits (util.js:957:11)
at Object.<anonymous> (/Users/user/Documents/NodeJS/fileevent.js:15:6)
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)`
Any help is appreciated! TIA!
Your mistake is here:
var eventEmitter = require('events').eventEmitter;
The EventEmitter object is title-case, since it is a class name. It could be corrected by rewriting it as:
var EventEmitter = require('events').EventEmitter;
but that is the obsolete way of importing the EventEmitter class for Node.js v0.10.x and earlier, which is only supported now for backwards compatibility. The recommended way to import it is:
const EventEmitter = require('events');
and refactor the rest of your references from eventEmitter to EventEmitter in order to follow the convention of naming classes with a capital letter.

Resources