serialport.js undefined ansi stream - javascript

I'm trying to use serialport.js, even just including it at the moment causes a runtime error TypeError: undefined is not an object (evaluating 'stream._ansicursor').
var React = require('react')
var SerialPort = require('serial port')
The context of this is within a react app, so its being compiled from jsx. I have no idea what or how this error came about, looking in at the line given in the error its coming from this code thats coming from serial port.js.
/**
* Creates a Cursor instance based off the given `writable stream` instance.
*/
function ansi (stream, options) {
if (stream._ansicursor) {
return stream._ansicursor
} else {
return stream._ansicursor = new Cursor(stream, options)
}
}
module.exports = exports = ansi

The serialport package you are trying to use operates on nodejs streams, this means it will need to run on the server within the nodejs context.
Depending on what you're trying to do with the serial port package, if you want to continue to have a React based web UI for this task, you will need to separate out the serialport actions and write an API using a nodejs framework. I'd suggest something like ExpressJS.
This way you can send requests to API urls that will perform the serialport tasks on the server and return JSON feedback that your web application, written in React, can interact with.

Related

Expose NodeJS Methods (FS) in Electron Renderer

I am using Quasar v2 for my Electron app development.
In this version, native node modules will no longer work on the renderer processes.
To get around this, there is electron-preload.js where we can access these node methods and expose them to the other parts of the app.
So I did this to expose fs:
import { contextBridge } from 'electron'
contextBridge.exposeInMainWorld('electronFs', require('fs'))
Then on my Vue/js files:
const fs = window.electronFs || require('fs')
fs.lstatSync(somePath).isFile()
But then I am getting fs.lstatSync(...).isFile is not a function. Any thoughts how can I make this work?
This is just for a local application (no web connectivity).
Thanks!
By default, Main process doesn't share the same context as Renderer's. And Preload runs in a context of Renderer's but isolated. Instead of exposing native Nodejs APIs to Renderer insecurely, even though you're building a local app, you may still use IPC to expose limited interfaces to Preload of Renderer process, then use contextBridge to expose APIs to Renderer. Here are some demo snippets.
/* Main.js */
const fs = require('fs');
const {ipcMain} = require('electron');
ipcMain.handle('isFile', (path) =>
fs.lstatSync(path).isFile()
)
/* Preload.js */
import {ipcRenderer, contextBridge} from "electron";
contextBridge.exposeInMainWorld('myAPIs', {
isFile: (path) => ipcRenderer.invoke('isFile')
}
/* index.vue */
myAPIs.isFile('path-to-file');
That happens because, in Electron, the backend and the UI don't share the same process (they run in different threads) because if you allow exposing native node APIs into the user context (the UI that runs finally in Chromium), it means that any time external javascript is loaded, they can access all those native APIs in the user computer.
So, those variables get transported to one thread to the other using IPC (Inter-process Communication), is just data, need to be primitives, if not they get serialized to primitives in the end (types of variables with no methods or objects like string, numbers, dates, or objects as string or binary), so probably to send those object from the parent context to the UI context Electron probably removes all non-serializable properties (so no functions).
Don't do that, is extremely insecure, just move data from one side to the other, which is very similar to using WebSockets.

Update local JSON file in Vue.js

I am pretty new in Vue.js and I faced with the issue, that I can't update/write some data in my local JSON file.
Let's say that I have data.json
And I would like to add a new entry to this file.
I use the basic code :
let d = JSON.stringify({ x: 5, y: 6 });
const fs = require('fs');
try {
fs.writeFileSync('data.json', d, 'utf-8');
}
catch (e)
{
alert(e);
}
As results I have an error message:
"TypeError: fs.writeFileSync is not a function"
How do I resolve this?
Vue.js is a front-end framework. It runs in the user's browser, so it doesn't have direct access to files on the server. The fs module you're trying to use exists only in node.js, which runs on the server. That's why it appears to be undefined when you try to access it from your front-end vue code.
If you want to change files based on user actions, you need to set up a server for vue to send requests to, and have the server modify the files. Although, if you're trying to write changes to a JSON file, you probably want a database instead. Maybe take a look at MongoDB?

How to export an object from a separate file to both Node and Javascript?

I have a file called utils.js which has some constants and I'm building a socket app which uses Node for backend work and regular Javascript for frontend. The names of the socket events are identical in both frontend and backend so I want to use the constants both in backend and frontend. But the syntax for exporting/importing is different in ecmascript6 as opposed to Node so how do I pull this off?
This is the contents of utils.js:
const EVENTS = {
CONNECTION: 'connection',
MESSAGE: 'message'
};
Object.freeze(EVENTS);
module.exports = EVENTS;
You can put the objects in JSON file, like events.json, or even event.js is you want plain JS objects. Both the Node and JS have access to this. Then you require/import this file in utils.js and you can do the same on the front end. Front and back ends can handle these however they want.

Make hapi plugin available in modules

I'm refactoring my Hapi server to use reusable modules instead of performing logic in my route handlers. I have a plugin registered in my Hapi server for MongoDB connection pooling, which I'd like to be able to access in these modules. Is there a way to export the server object itself, or do I need to rewrite my modules to accept the request object as an argument? I'm using node 0.12.12 and Hapi 8.4.0.
I already tried module.exports = server; in the file where my server is defined, and then requiring the server object from a different file, (both with var server = require('../index.js').server; and var server = require('../index.js')(server);, but I either get an error or undefined.
The closest thing I could find to an answer was this issue from a few years ago, on an older version of Hapi: https://github.com/hapijs/hapi/issues/1260
- but it looks like this was never really resolved.
Well, I'm an idiot, but maybe this will help somebody else out:
It seems module.exports cannot be called within a callback, according to the node documentation. So I moved this statement to the bottom of my index.js:
module.exports.server = server
And then in my other modules, called:
var server = require('../index.js');
And was able to access the plugins contents as server.server.plugins
HTH

var connect = require('connect'); var app = connect(), What is connect()? is it a method or a constructor?

Im fairly new to Nodejs and connect, I was looking through some tutorials and examples and come across .
What is the purpose of connect() and is it a method or a constructor?
var connect = require('connect');
var app = connect(),
Connect is an extensible HTTP server framework for node, providing
high performance "plugins" known as middleware.
according to link this site
for more info about connect and middleware please refer this like npmjs
When you require a module, it returns it's exports property. In the connect module they set the module.exports to be a function, that creates an app. In modules that returns an object with multiple functions (like fs), you can call its functions ( like fs.open() ), but this time you get a function, so you can just call connect(), and it returns a new instance of an app.

Categories

Resources