fs.readFileSync is not a function when importing an object - javascript

I am developing in vuejs, focused on IPTV service. The problem I am having is that when I want to do the following
const {channels} = require('../lib/utils/index.js');
in the file actions.js it shows me the following error
index.js?c45a:26 Uncaught TypeError: fs.readFileSync is not a function
at Module.eval (index.js?c45a:26)
at eval (index.js:64)
at Module../src/lib/utils/index.js (app.js:958)
at __webpack_require__ (app.js:786)
at fn (app.js:151)
at eval (actions.js?63e0:2)
at Module../src/store/actions.js (app.js:1005)
at __webpack_require__ (app.js:786)
at fn (app.js:151)
at eval (index.js?4360:1)
Is there any way to solve this problem?
../lib/utils/index.js
const fs = require('fs');
const fetch = require('node-fetch');
const parser = require('iptv-playlist-parser');
const USM3U = require('./urls/us.m3u');
/***
* #async
* #method GM3U
* #param {empty}
* #Summary Generate US m3u file
* #Description THIS FUNCTION SHOULD NOT BE USED.
***/
const GM3U = async() =>{
const res = await fetch(`${USM3U}`);
const data = await res.text();
fs.writeFile('us.m3u' , data , (err) =>{
if(err){
console.log(err);
}else{
console.log('The file us.m3u was saved!');
}
})
};
const usPlaylist = fs.readFileSync('us.m3u' , {encoding: 'utf8'});
const channels = parser.parse(usPlaylist);
module.exports = {
channels
};
actions.js
When I try to make the import I get the error Uncaught TypeError: fs.readFileSync is not a function
const {channels} = require('../lib/utils/index.js');

You can't use fs package with Vue.js framework .Because fs is not frontend technology . Instead of that try to use AJAX call to solve your issue .

Related

Error occurred while pinning file to IPFS: TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string

When i add the files to another project I get the following error and i can't figure out why.
When I run "node scripts1/runScript.js" error i get is:
Error occurred while pinning file to IPFS: TypeError [ERR_INVALID_ARG_TYPE]: The "url" argument must be of type string. Received undefined
at new NodeError (node:internal/errors:371:5)
at validateString (node:internal/validators:119:11)
at Url.parse (node:url:169:3)
at Object.urlParse [as parse] (node:url:156:13)
at dispatchHttpRequest (C:\Users\alaiy\Documents\NFTs\nft-mix-main\node_modules\axios\lib\adapters\http.js:118:22)
at new Promise (<anonymous>)
at httpAdapter (C:\Users\alaiy\Documents\NFTs\nft-mix-main\node_modules\axios\lib\adapters\http.js:48:10)
at dispatchRequest (C:\Users\alaiy\Documents\NFTs\nft-mix-main\node_modules\axios\lib\core\dispatchRequest.js:58:10)
at Axios.request (C:\Users\alaiy\Documents\NFTs\nft-mix-main\node_modules\axios\lib\core\Axios.js:108:15)
at wrap (C:\Users\alaiy\Documents\NFTs\nft-mix-main\node_modules\axios\lib\helpers\bind.js:9:15) {
code: 'ERR_INVALID_ARG_TYPE'
}
The runScript.js code is :
const path = require('path');
const pinFileToIPFS = require('./pinFileToIPFS');
const filePath = path.join(__dirname, '../img/Toad-Licking-Mario.jpg');
// const filePath = path.join(__dirname, '../data/metadata.json');
pinFileToIPFS(filePath);
The pinFileToIPFS.js file which contains the "url: pinataEndpoint" i think the error message is referring too:
require('dotenv').config();
const fs = require('fs');
const axios = require('axios');
const FormData = require('form-data');
const { storeDataToFile } = require('./ipfsHelper.js');
// Calls Pinata API's to pin file to IPFS
const pinFileToIPFS = async (filePath) => {
const pinataEndpoint = process.env.PINATA_ENDPOINT;
const pinataApiKey = process.env.PINATA_API_KEY;
const pinataApiSecret = process.env.PINATA_API_SECRET;
const form_data = new FormData();
try {
form_data.append('file', fs.createReadStream(filePath));
const request = {
method: 'post',
url: pinataEndpoint,
maxContentLength: 'Infinity',
headers: {
pinata_api_key: pinataApiKey,
pinata_secret_api_key: pinataApiSecret,
'Content-Type': `multipart/form-data; boundary=${form_data._boundary}`,
},
data: form_data,
};
console.log('request:', request);
const response = await axios(request);
console.log('Successfully pinned file to IPFS : ', response);
await storeDataToFile(response.data);
console.log('Successfully added IPFS response to json file');
} catch (err) {
console.log('Error occurred while pinning file to IPFS: ', err);
}
};
module.exports = pinFileToIPFS;
Lastly my .env file is:
# export PRIVATE_KEY=asafdagadd
# export WEB3_INFURA_PROJECT_ID=asdfsdf
# export ETHERSCAN_TOKEN=asdfasdfasdf
export IPFS_URL=blah blah
export UPLOAD_IPFS=true
export PINATA_API_KEY='blah blah'
export PINATA_API_SECRET='blah blah'
export PINATA_ENDPOINT="https://api.pinata.cloud/pinning/pinFileToIPFS"
I can upload the package.json file aswell if needed.
Any help is appreciated!
SOLUTION: Turned out the export syntax I was using in my .env file should not be there. export syntax is for python scripts which I was previously using.
As I am running javascript scripts, I deleted the export syntax and everything worked like a charm!
I was facing same error, the i find out that my config folder suppose to be in the folder in which I was executing it from.
This error comes when your url value is not getting the env variables.
So in my case solution was something like this-
config/
--default.json
scripts/
--server.js
So it was searching config folder inside scripts folder.
Later I run my file outside from scripts folder then it worked fine.
node scripts/server.js

Bind problem in SQL query in Node, Express, Mysql2 app

I have been following a tutorial on setting up REST APIs in Node, using Express for an app that accesses an existing MariaDB database. My version only needs to read data and I have the DB co-located with the Node application (same host).
My goal for this entry-level example is to just access the data, using static SQL, so I can see it rendered in the web page by the JSON pritifier.
[Next, I want to present the data in a table (EJS?). Later, when I can get that to work, I'll add form controls (React?) to let a user specify start and end date bounds for the SQL query. Finally I'll aim to render the data as a line graph (D3js).]
The tutorial runs the web server successfully (it returns 'OK' on the base URL), but when I go to URL/solarData it tries an async function to getMultiple rows from the DB, it responds:
Bind parameters must not contain undefined. To pass SQL NULL specify JS null TypeError: Bind parameters must not contain undefined. To pass SQL NULL specify JS null
at /SunnyData/solarViz/node_modules/mysql2/lib/connection.js:628:17
at Array.forEach (<anonymous>)
at Connection.execute (/SunnyData/solarViz/node_modules/mysql2/lib/connection.js:620:22)
at /SunnyData/solarViz/node_modules/mysql2/promise.js:120:11
at new Promise (<anonymous>)
at PromiseConnection.execute (/SunnyData/solarViz/node_modules/mysql2/promise.js:117:12)
at Object.query (/SunnyData/solarViz/services/db.js:6:40)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async Object.getMultiple (/SunnyData/solarViz/services/solarData.js:7:16)
at async /SunnyData/solarViz/routes/solarData.js:8:14
app.js:61
./app.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3800;
const solarDataRouter = require('./routes/solarData');
app.use(express.json());
app.use(
express.urlencoded({
extended: true,
})
);
app.get('/', (req, res) => {
res.json({'message': 'ok'});
})
app.use('/solarData', solarDataRouter);
/* Error handler middleware */
app.use((err, req, res, next) => {
const statusCode = err.statusCode || 500;
console.error(err.message, err.stack);
res.status(statusCode).json({'message': err.message});
return;
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
});
./routes/solarData.js
const express = require('express');
const router = express.Router();
const solarData = require('../services/solarData');
/* GET solar data. */
router.get('/', async function(req, res, next) {
try {
res.json(await solarData.getMultiple(req.query.page));
} catch (err) {
console.error(`Error while getting solar data `, err.message);
next(err);
}
});
module.exports = router;
./config.js
const env = process.env;
const config = {
db: {
host: env.SUNNY_HOST,
user: env.SUNNY_USER,
password: env.SUNNY_PW,
database: env.SUNNY_DB,
},
listPerPage: env.LIST_PER_PAGE,
};
module.exports = config;
./services/solarData.js
const db = require('./db');
const helper = require('../helper');
const config = require('../config');
async function getMultiple(page = 1){
const offset = helper.getOffset(page, config.listPerPage);
const rows = await db.query(
`SELECT * FROM DTP LIMIT ?,?`, [offset, config.listPerPage]
);
const data = helper.emptyOrRows(rows);
const meta = {page};
return {
data,
meta
}
}
module.exports.getMultiple = getMultiple;
./services/db.js
const mysql = require('mysql2/promise');
const config = require('../config');
async function query(sql, params) {
const connection = await mysql.createConnection(config.db);
const [results, ] = await connection.execute(sql, params);
return results;
}
module.exports = {
query
}
I've left out the ./helper.js
Everything runs fine until I direct the webpage to /solarData. At that point I get the Debug Console (vscode) mentioned up-front
Searching seems to point at a mysql2 shortcoming/bug but not at a practical solution
If you respond, please describe the 'bind' mechanism, as I'm not sure what's going on.
Hope I've put enough info in. Please ask if I need to add anything else.
The error says
Bind parameters must not contain undefined.
It means that in the file ./services/solarData.js on the line
const rows = await db.query(
`SELECT * FROM DTP LIMIT ?,?`, [offset, config.listPerPage]
);
Some of the 2 variables is undefined, you need to check offset and config.listPerPage to be defined.
Just use
console.log('offset: ' + offset)
console.log('listPerPage: ' + config.listPerPage)
and you will find out what is undefined in your case

nodejs module throws error but same code worked in main js file

I want to know why this custom module is not working
module:
var mariadb = require('mariadb');
class DB{
constructor(){
this.db_conn = null;
this.db_pool = mariadb.createPool({
host:"localhost",
user:"root",
password:"",
database:"testdatabse"
});
this.db_pool.getConnection().then(conn => {
this.db_conn = conn;
});
}
};
module.exports = function(){
return (new DB()).db_conn;
}
but the same code working in main javascript file
main file here:
var http = require('http');
var url = require('url');
var mariadb = require('mariadb');
var dbs = require('./modules/mariadb-connector'); //here i am importing the module
var db_conn;
var db = mariadb.createPool({
host:"localhost",
user:"root",
password:"",
database:"testdatabase"
});
db.getConnection().then(conn => {
db_conn = conn;
});
console.log(dbs.query("SELECT * FROM array_languages")); //here it's throwing error
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'application/json'});
console.log(req.url);
db_conn.query("SELECT * FROM array_languages").then(data => {
res.write(JSON.stringify(data));
res.end();
});
}).listen(8080,"localhost");
error:
PS D:\Programs\nodejs\test> node index.js
D:\Programs\nodejs\test\index.js:16
console.log(dbs.query("SELECT * FROM array_languages"));
^
TypeError: dbs.query is not a function
at Object.<anonymous> (D:\Programs\nodejs\test\index.js:16:17)
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
here the error when I tried to use this module
at console.log(dbs.query("SELECT * FROM array_languages"));
please explain why is working in main js file but not in module.
is there any way to achieve this
var dbs = require('./modules/mariadb-connector')
sets dbs to the exports object of the custom module, which is a function to return a connector to a new db:
function(){
return (new DB()).db_conn;
}
You could try calling the exports module when setting dbs like
var dbs = require('./modules/mariadb-connector')();
However, this leave the problem that the .db_conn property of new DB() is set asynchronously in a promise callback. Immediately after requiring the module db-conn in the module will still be null.
Some form of asynchronous processing needs to be implemented, taking into consideration that at the moment there is a race condition between getting the database connection and servicing a request to look up the database. At the moment setting up the connection wins the race: this is the only reason it appears to work when the connection code is in the main module.
An Outline of asynchronous processing for ideas:
var http = require('http');
var url = require('url');
var mariadb = require('mariadb');
async function db_conn() {
let db_pool = mariadb.createPool({
host:"localhost",
user:"root",
password:"",
database:"testdatabse"
});
const conn = await db_pool.getConnection();
return conn;
}
db_conn().then( db_conn => {
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'application/json'});
console.log(req.url);
db_conn.query("SELECT * FROM array_languages").then(data => {
res.write(JSON.stringify(data));
res.end();
});
}).listen(8080,"localhost");
})
.catch( err=> {
console.error( err));
process.exit(1);
});
Well, it's not the same code, is it? Your problem is here:
this.db_pool.getConnection().then(conn => {
this.db_conn = conn;
});
This is an async function. It will finish running after the constructor has run. You're importing return (new DB()).db_conn when db_conn is null.
If you're set on using it as a class, I'd create a method getConnection that got the value from db_conn after it has finished running, and import the instance instead of the the property

Serial Port With Electron-Vue.js

I tried to do serial port to listen my COMports with electron-vue.js.
When I try to code this below.
const SerialPort = require("serialport");
const Readline = SerialPort.parsers.Readline;
const port = new SerialPort("COM3", {
baudRate: 9600,
});
const parser = new Readline();
port.pipe(parser);
//Read Data
parser.on("data", (line) => {
console.log(line);
});
//Send Data
parser.write("Sended Data !");
I got this below error in console.
TypeError: Cannot read property 'modules' of undefined
at Object.eval (bindings.js?dfc1:29)
at eval (bindings.js:223)
at Object../node_modules/bindings/bindings.js (0.js:231)
at webpack_require (app.js:854)
at fn (app.js:151)
at eval (linux.js?88eb:2)
at Object../node_modules/#serialport/bindings/lib/linux.js (0.js:65)
at webpack_require (app.js:854)
at fn (app.js:151)
at Object.eval (index.js?c888:14)
How can I solve this problem ?
By the way, When I try to run this code in node.js, it runs. But when I try to run this code in Vue.js, it did not run.
Thanks
serialport uses physical resource so can't be webpacked as client package. you need to mark serialport as external for the builder.
// vue.config.js
module.exports = {
pluginOptions: {
electronBuilder: {
externals: ["serialport"],
},
},
},

Node-serial port as external module in webpack - module not found

I'm trying to get node-serialport to work with electron and webpack.
I'm importing serialports as external module:
# webpack.config.js
externals: {
serialport: "serialport"
}
This is the code in my app:
// read NMEA data from serial port
const SerialPort = require('serialport');
console.log(SerialPort.list());
const Readline = SerialPort.parsers.Readline;
const port = new SerialPort('/dev/tty.Redmi-ShareGPS', { baudRate: 4800 });
const parser = port.pipe(new Readline({ delimiter: '\r\n' }));
// Open errors will be emitted as an error event
port.on('error', function(err) {
console.log(err.message);
})
// send NMEA data to GPS.js
parser.on('data', function(data) {
// gps.update(data);
});
Trouble is in first line: const SerialPort = require('serialport');
Webpack compiles everything without error, but I have a browser console error:
Uncaught ReferenceError: serialport is not defined
at Object.<anonymous> (bundle.js:65651)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:65630)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:31520)
at __webpack_require__ (bundle.js:20)
at Object.<anonymous> (bundle.js:25595)
at __webpack_require__ (bundle.js:20)
at _ol_ (bundle.js:63)
at bundle.js:66
Which origins at this in webpack generated bundle.js:
/* 315 */
/***/ (function(module, exports, __webpack_require__) {
// read NMEA data from serial port
const SerialPort = __webpack_require__(316);
console.log(serialport.list());
const Readline = SerialPort.parsers.Readline;
const port = new SerialPort('/dev/tty.Redmi-ShareGPS', { baudRate: 4800 });
const parser = port.pipe(new Readline({ delimiter: '\r\n' }));
// Open errors will be emitted as an error event
port.on('error', function (err) {
console.log(err.message);
});
// send NMEA data to GPS.js
parser.on('data', function (data) {
// gps.update(data);
});
/***/ }),
/* 316 */
/***/ (function(module, exports) {
module.exports = serialport;
/***/ })
/******/ ]);
The error line is exactly module.exports = serialport;
According to webpack docs on externals, I suppose I somehow need to include serialport as a global variable, but the example is for jQuery which is a js file, and serialport is node module.
How to make it work?
After many hours of frustration, I moved
const SerialPort = require('serialport');
from javascript file which is supposed to be bundled by webpack to index.html:
<script>
const SerialPort = require('serialport');
</script>
<script src="dist/bundle.js"></script>
SerialPort is now recognized.
Also, it seems like webpack-dev-server doesn't work very well with Electron and serialport. I have to launch full electron app.
Try remote.
You might also want to try using remote:
const SerialPort = require( "electron" ).remote.require( "serialport" );
use eval
const serialport = eval(`require('serialport')`)

Categories