I'm new at nodejs and I want to write to a serial port using node but now I want it to be triggered by a button. And the data is coming from a textbox.
My node script is doing fine when I run it in the console/terminal. But can't do it with a button in a webpage.
Here's my nodejs embedded in html
<!DOCTYPE html>
<html>
<head>
<title>Node x HTML</title>
</head>
<body>
<script>
function write_serial()
{
var serialport = require("serialport");
var SerialPort = serialport.SerialPort;
var sp = new SerialPort("/dev/ttyACM0", {
baudrate: 9600,
parser: serialport.parsers.readline("\n")
});
var text = document.getElementById("textbox1").value;
sp.on('open', function()
{
sp.on('data', function (data)
{
sp.write(name);
});
});
}
</script>
<Input Type = "text" id = "textbox1" >
<BR>
<br><button onclick="write_serial();" href="javascript:;">Go!</button>
</body>
</html>
Here's the error I got when I open the console of the page (F12)
ReferenceError: require is not defined
Thanks in advance for your help. :)
Node.js is a hosting environment, that can execute JS and provides Node.js specific API. Browser, is a different hosting environment, with different API's. You can't use Node's specific API in a browser, and JS that uses Node API will result in an error in a browser.
For example, your script is using global require function, which is not available in a browser API's. And that's why:
ReferenceError: require is not defined
Conversely, your script can't be executed on Node as well, since it uses browser API:
document.getElementById("textbox1")
You've mixed API's from different environments in one script.
However, if your JS script doesn't use Node or browser specific API, it can be executed in both Node and a browser without an error. But it's not the case with your script.
The solution to your problem can be to split your script into two separate scripts, run one in a browser, and the other in Node.js, and to exchange data between them using XMLHttpRequest.
NodeJS is a non-browser JavaScript environment. You can't use most NodeJS features in a browser environment, because they aren't designed for it.
Instead, you'd have a local NodeJS process providing a web endpoint (e.g., a web server; perhaps using Express, but you don't have to) and run that NodeJS process so it's listening for web requests. Then you'd have a button on your web page that makes an ajax call to the NodeJS server, which performs the work.
Naturally, this would only allow you to perform the work on the machine where the server process is running.
Maybe import the serialport module from https://wzrd.in/standalone/serialport#latest
In other hand, try to seperate the logic from the view, i don't know if your app will grow or if it's just a POC, but use a messageBroker or sockets to bind your actions'view with the engine ?
Hope it helps
Related
I want to move a txt file from drive c to drive d and I found this code by searching but it does not work properly.
please guide me.
Thanks
<html>
<body>
<script language="JScript">
function move() {
var object = new ActiveXObject("Scripting.FileSystemObject");
var file = object.GetFile("C:\\1.txt");
file.Move("d:\\");
console.log("File is moved successfully");
}
</script>
<button onClick="move()">Move File txt</button>
</body>
</html>
Browsers do not provide any features that let code provided by a webpage move files the users' hard disks.
The code you've found may have worked in old versions of Internet Explorer (I think the feature was removed in later versions) but only when the security settings were altered from the default to allow it.
You could probably use it in server-side Classic ASP (but then it would move files on the server rather than the client).
For a browser-style UI which can do this, look to tools like Electron which pair a custom browser with Node.js in a desktop application. You can then use the Node.js side of your custom application to move files.
Obviously this will require that the user download and install your application and use that instead of their web browser.
I want to use pouchDB in my WebApp so that when I click on a button, the data from a JSON file would be saved to pouchDB. In my index.html I imported these at first:
<script type="module" src="pouchdb/packages/node_modules/pouchdb/src/pouchdb.js"></script>
<script type="module" src="pouchdb-load/dist/pouchdb.load.js"></script>
<script src="js/pdb.js"></script>
I cloned pouchDB to my working html folder so the path should be fine. But in my js file it started to throw error from this line var PouchDB = require('pouchdb'); stating 'Uncaught ReferenceError: require is not defined', which I think it means that my WebApp failed to reach pouchDB from the src.
What I've tried:
Use <script src="//cdn.jsdelivr.net/npm/pouchdb#7.2.1/dist/pouchdb.min.js"></script> in the html file instead of using pouchdb.js in the js folder as the source.
This is also the only source this PouchDB official guide uses in its todo demo. This demo worked perfectly on my laptop, but when it comes to my own WebApp it no longer works and still throws the same error.
Another problem for this method is that even if the cdn link worked and I could reach pouchdb.min.js, I still need the pouchdb.load.js to be able to work since I want data in the JSON file to be saved to pouch.
In the PouchDB official guide, it doesn't even included this line var PouchDB = require('pouchdb'); in its app.js, but directly says var db = new PouchDB('todos');. But when I attempted to do it this way, a new error occurred: 'ReferenceError: PouchDB is not defined'.
I also tried npm install pouchdb-browser and then in the js file I wrote:
var PouchDB = require('pouchdb-browser');
var pouchdb = PouchDB.default.defaults();
but it throws the same error associated with require.
I think the problem is still that the sources in the html failed to created this connection between pouchdb.js with my WebApp. Meanwhile everything seems fine when I followed the official guide to make the todo Demo. Any idea what might have caused this problem and how to solve it?
I think you're mixing up client side and server side programming. You can't do "require" natively in client-side JavaScript code. Here's a very simple example of taking data from a form and writing it to local PouchDB:
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/pouchdb#7.2.1/dist/pouchdb.min.js"></script>
</head>
<body>
<textarea id="doc" rows="10">
{
"a": 1
}
</textarea>
<br>
<button onclick="save()">Save</button>
<div id="response"></div>
<script>
const db = new PouchDB('todos')
const save = async function() {
const el = document.getElementById('doc')
const doc = JSON.parse(el.value)
const response = await db.post(doc)
document.getElementById('response').innerHTML = JSON.stringify(response)
}
</script>
</body>
</html>
It gets PouchDB from the CDN - notice that I'm using https:// instead of // as the protocol because we always want to fetch PouchDB using https even if the hosted page is served out on http.
Once PouchDB is loaded, we write the document to PouchDB database using the post function and write the response back to the page.
I have a library with HTML-form like this:
code.gs:
function openDialog() {
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile("h"), "Test" );
}
function hello() {
console.log('booo');
}
h.html:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<button id="b">Click me</button>
<script>
var b = document.getElementById('b');
b.onclick = function() {
google.script.run
.withSuccessHandler(function(str){window.alert("executed");})
// .withFailureHandler(function(error){window.alert("failed");})
.hello();
}
</script>
</body>
</html>
I shared this script for view and deployd it as a library. Next I created a bound script in Google Sheet with this code:
function onOpen() {
SpreadsheetApp.getUi().createMenu('test').addItem('run', 'myFunction').addToUi();
}
var hello = function() {};
function myFunction() {
TT.openDialog();
}
I've added the library with identifier: TT.
Next I refreshed my Google Sheet file with bound code to see the menu "test", ran test > run. The HTML-window appeared. When I clicked the button, nothing happened. When I opened console, I saw the error:
This error does not appear if I do not use library.
I have experienced the same situation with you. In my case, the reason of the issue was due to the authorization at the library side.
When the authorization process for using the scopes in the library is NOT done at the library side, I confirmed that the error of Uncaught occurred.
When the authorization process for using the scopes in the library is done at the library side, I confirmed that the error of Uncaught didn't occur.
Namely, in my environment, I confirmed that when the library is used for your situation, it was required to authorize the scopes for both the client side and the library side.
So, as a workaround, I used the following flow.
Workaround:
Create a Google Apps Script library.
Please copy and paste your script of code.gs and h.html to the standalone script or the container-bound script.
Deploy the Google Apps Script as the library.
In your script, for example, please directly run hello() at the library side, and authorize the scopes.
Install the library to the client side and load the library from the client side.
Please run myFunction() at the client side.
By this flow, when you run run at the custom menu and click the button, the dialog of executed is opened.
Note:
In this case, when I wanted to make users use the client script, it was required to authorize the scopes for both the client side and the library side. I thought that this may be a little inconvenient.
So, how about reporting this for the Google issue tracker? Ref Unfortunately, I couldn't find the issue tracker with the same situation.
Added:
As the method for authorizing the scopes at the library side from the client side, I would like to propose to use Web Apps. I thought that when the Web Apps is used, the authorization of the library side can be done at the client side. By this, I thought that the inconvenience may be resolved a little.
Please do the following flow.
1. Library side.
Please copy and paste the following scripts.
Google Apps Script: code.gs
function openDialog() {
SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile("h"), "Test" );
}
function hello() {
console.log('booo');
}
function doGet() {
return HtmlService.createHtmlOutput("ok");
}
HTML: h.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<button id="b">Click me</button>
<script>
var b = document.getElementById('b');
b.onclick = function() {
google.script.run
.withSuccessHandler(function(str){window.alert("executed");})
// .withFailureHandler(function(error){window.alert("failed");})
.hello();
}
</script>
</body>
</html>
2. Deploy Web Apps at library side.
Please deploy Web Apps at the library side. About the method for this, you can see the official document. Ref The detail setting is as follows.
Execute as: User accessing the web app
Who has access: Anyone with Google account
3. Deploy as library.
Please deploy as the library. Ref
4. Client side.
Please install the library to the client side. And, please copy and paste the following scripts. In this case, please replace https://script.google.com/macros/s/###/exec with your Web Apps URL.
function onOpen() {
SpreadsheetApp.getUi().createMenu('test').addItem('auth', 'auth').addItem('run', 'myFunction').addToUi();
}
var hello = function() {};
function myFunction() {
TT.openDialog();
}
function auth() {
const html = HtmlService.createHtmlOutput(`<input type="button" value="Authorize" onclick="window.open('https://script.google.com/macros/s/###/exec', '_blank');google.script.host.close()">`);
SpreadsheetApp.getUi().showDialog(html);
}
5. Testing.
At first, please run auth at the custom menu. By this, you can authorize the scopes of both the client side and the library side. When the new tab is not opened when auth is run, please run auth() at the script editor again.
As the next step, please run run. By this, your dialog is opened. And, when both authorizations (client and library side) with auth has already been finished, when you click the button, the dialog of executed is opened.
References:
Web Apps
Taking advantage of Web Apps with Google Apps Script
I want to fetch some information from a website using the phantomjs/casperjs libraries, as I'm looking for the HTML result after all javascripts on a site are run. I worked it out with the following code from this answer:
var page = require('webpage').create();
page.open('http://www.scorespro.com/basketball/', function (status) {
if (status !== 'success') {
console.log('Unable to access network');
} else {
var p = page.evaluate(function () {
return document.getElementsByTagName('html')[0].innerHTML
});
console.log(p);
}
phantom.exit();
});
And I also worked it out to get phantomjs/casperjs running on heroku by following these instructions, so when I now say heroku run phantomjs theScriptAbove.js on OS X terminal I get the HTML of the given basketball scores website as I was expecting.
But what I actually want is to get the html text from within a Mac desktop application, this is the reason why I was looking for a way to run the scripts on a web server like heroku. So, my question is:
Is there any way to get the HTML text (that my script prints as a result) remotely within my Objective-C desktop application?
Or asked in another way: how can I run and get the answer of my script remotely by using POST/GET?
p.s.
I can handle with Rails applications, so if there's a way to do this using Rails - I just need the basic idea of what I have to do and how to get the phantomjs script to communicate with Rails. But I think there might be an even simpler solution ...
If I understand you correctly you're talking about interprocess communication - so that Phantom's result (the page HTML) can somehow be retrieved by the app.
per the phantom docs, couple options:
write the HTML to a file and pick up the file in your app
run the webserver module and do a GET to phantom, and have the phantom script respond with the page HTML
see http://phantomjs.org/api/webserver/
I m trying to open Notepad, Calculator in button click in asp.net with code behind C#. I tried with the code
System.Diagnostics.Process.Start("c:\\windows\\system32\\notepad.exe");
this is working fine in local system but not working in the Server. I even tried with the javascript
function executeCommands(inputparms)
{
alert('ff');
var oShell = new ActiveXObject("Shell.Application");
var commandtoRun = "C:\\Winnt\\Notepad.exe";
if (inputparms != "")
{
var commandParms = document.form1.filename.value;
}
oShell.ShellExecute(commandtoRun, commandParms, "", "open", "1");
}
even this is not working out. Can you please suggest me in on how to open the notepad application in the client end with out disturbing server notepad.
This can't be done. Imagine the security mess we'd be in if a web-page could run arbitrary programs on a client machine. Oh wait... ;-)
This is not possible (in general, though you could possibly get around with with various applets and browser plugins). In fact, I would be quite mortified if any web page could execute an arbitrary program on my computer.
You cannot do this. ASP.NET runs on the server and you cannot run programs on the client computer. The ActiveX object you have shown should work but only in IE and only after the user explicitly authorizes the execution of it. Also the location of notepad.exe might differ depending on the client (could be c:\windows, c:\winnt, ... and some clients running for example on Linux or MacOS don't have such executable)
What you are trying to achieve is not possible because of the nature of application in case of ASP.Net. The application will execute on server and will only send client side HTML to client. Even if your code is syntatically correct, it would open up the utilities on server itself.
This Can be possible by using below code on click of server button or Link.
System.Diagnostics.Process.Start("notepad.exe");
System.Diagnostics.Process.Start("C:\Windows\System32\calc.exe")
Works fine, though you may have to adjust settings on your browser. Be sure calc.exe is in the directory.