node-webkit tail a file output in application console - node.js

Pardon me if I am totally wrong in some concepts but I am a novice to all of it - node js, node-webkit, javascript. I am trying to learn all of them together :)
I am developing a simple desktop app using node-webkit where I want to read the system log and write it in the application console. I am using tailfd node module and there is no error in the console. here is my html
<!DOCTYPE html>
<html>
<head>
<title>Tailing system log</title>
</head>
<body>
<script>
var tail = require('tailfd').tail,
watcher = tail('/var/log/system.log',function(line,tailInfo) {
//default line listener. optional.
console.log('line of data> ',line);
});
</script>
<h1>Tailing sys log!</h1>
</body>
</html>
The tail output is not showing up in the app console. Can you point me if am missing any basic stuff? Any help would be appreciated.

Related

How do I get a Electron app object through HTML (script tag)?

So I have here this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Oh no!</title>
</head>
<body>
<label>Oh dear. A serious error occurred and the app needs to restart. Press the button below to restart.</label>
<br>
<button onclick="restart()">Restart</button>
<script>
const { app } = require("electron")
function restart() {
app.relaunch()
app.exit()
}
</script>
</body>
</html>
And now, when the app receives an unhandled error this will show... but when the user clicks the button, the app doesn't restart so how would I make the app restart?
You can't get the app object without using preload.js and neither is directly getting the app object safe. There is a method to do the above using preload.js and ipcRenderer which are pure Electon APIs
In electron (even in web development), there is server-side code and browser-side code. The code written in between the script tags in your snippet is server side code which will fail to execute in browser side.
Server-side code in your case is in NodeJS Backend and browser-side code is the one which is the HTML Page and its own javascript.
So to close the window (which only NodeJS can do, i.e., the backend) you need to use Electron's ipcRenderer which helps string based communication between the browser-side javascript and the server-side javascript.
While creating a browser window in electron using new BrowserWindow(options) where options is an object. Define the object as:
options = {
webPreferences: {
preload: preload.js, //You need to create a file named preload.js (or any name) in your code
nodeIntegration: true,
contextIsolation: false,
}
}
Now in a new file called preload.js:
window.ipcRenderer = require('electron').ipcRenderer;
In your snippet you added const { app } ... which should be done this way to inject the javascript using a preload property in the object.
Now in the main app.js file (whatever you named maybe index.js) where you created the browser window:
const ipc = require('electron').ipcMain; //Add to your pre-existing code
ipc.on("close-app", (event, message) => { //"close-app" can be anything but, you need to use the same key in the send message side (later in this answer)
browserWindow.close(); //If you named the browserwindow as browserWindow
});
Now in your HTML (i.e., send message side)
...
<script>
window.ipcRenderer("close-app", ""); //Second parameter is used if you want to send some extra message. The extra message can be viewed in the server side from the message parameter in the app.js code (just above this paragraph)
</script>
This is a bit difficult if you are doing it for the first time.
I've added more articles which will help you clear your confusions:
Highlight about server-side and browser-side code
Relation with socket.io communication in NodeJS

How can I addEvent listeners in my node/express app?

I am still trying to get my head around what's possible with frontend vs backend. I still don't understand how to incorporate the likes of an eventListener into my app when I can't select the document.
I have created a script.js file and added it to my public directory:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Hours Calculator</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/styles.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
<script src="https://kit.fontawesome.com/391e6a689e.js" crossorigin="anonymous"></script>
<script src="/script.js"></script>
</head>
<body>
and I am serving this folder/files in my app.js like so:
app.use(express.static(__dirname + '/public'));
However I am unable to target anything in my script.js, for example:
let h1 = document.body.querySelector('h1');
h1.style.color = 'brown';
Doesn't work. h1 is undefined.
I am sure there is an extremely straight forward explanation but there are some gaps in my understanding and would like if someone can explain to me why this isn't working and how I can get the front end and the back end interacting.
The Node.js "events" module and the "EventEmitter" module facilitates communication between objects in Node. The EventEmitter module is at the core of Node's asynchronous event-driven architecture. Here is how you can create custom events and emit them:
const EventEmitter = require('events');
const myEmitter = new EventEmitter();
//Event Listener
const EventListenerFunc = () => {
console.log('an event occurred!');
}
//Registering the event with the listener
myEmitter.on('eventName', EventListenerFunc);
//Emitting the event
myEmitter.emit('eventName');
Javascript is a Scripting language. It is basically used on the client-side. JavaScript can run in any engine like JavaScript Core (Safari), Spider monkey (Firefox), V8 (Google Chrome).
NodeJS is a Javascript runtime environment. NodeJS code can be run outside the browser. It is mostly used on the server-side.
Node.js only runs in a V8 engine that is mainly used by Google Chrome. Nodejs comes with a lot of modules and mostly used in web development. Node.js makes the Javascript more powerful and adds many great features to it.
Node.js does not provide a built-in DOM, so you can't access document object in Node.js and there are several modules which can construct a DOM from a string of HTML source code. Two popular DOM modules are cheerio and jsdom. You can make use of these modules to have an access to DOM level manipulation of the data in your code.

React js : Rendering multiple index html in a single page applications

I am developing an E - Commerce website in React and Node.js. I am facing two problems described below.
I have two different master .html files for admin side and front end side. Hence I am using builtin React admin template in which index.html is loading on project start. My problem is how can I load another master .html for front end design?
I want to use Node.js as the back end. Hence I can not integrate node.js with React front or admin side which will run if the React application runs.
Any suggestions or solution steps will be highly appreciated.
Here's a very basic concept of the first idea:
const AdminIndexPage = children => (<section className="AdminIndexPage">{children}</section>)
const PublicIndexPage = children => (<section className="PublicIndexPage">{children}</section>
const App = props => {
if(props.indexPageToShow === 'admin'){
return <AdminIndexPage {...props} />
}else{
return <PublicIndexPage {...props} />
}
}
Here's a very basic concept of the second idea:
index.html
<html>
<head>
<script src="index.js"></script>
</head>
<body>
<div id="AdminPageIndex"></div>
<div id="PublicPageIndex"></div>
</body>
</html>
index.js
import {AdminPageIndex, PublicPageIndex} from './pages'
ReactDOM.render(AdminPageIndex, document.getElementById('AdminPageIndex'))
ReactDOM.render(PublicPageIndex, document.getElementById('PublicPageIndex'))

How do I send variables from Express to a dynamic page

I've recently switched from XAMPP/LAMP stack to MEAN stack and oh dear, these new things are amazing but I can't wrap my head around this.
In a LAMP stack, if you want to display some variable (like your username from a Database or some dynamic variable like that) you'd do something like this:
index.php
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<?php echo $some_var; ?>
</body>
</html>
and that's it. At the start of the file, you can pass the data from a Database to the variable and that would be it.
I don't understand how you achieve this in a MEAN stack.
Do I have to use a Template engine like EJS/Pug? If I understand it, I'd do back-end in the same file that Express is (like for example, selecting data from databases) and then I'd do something like this:
app.js
app.set("views", "./views");
app.set("view engine", "pug");
app.get("/", (req, res) => {
res.render("index", {message:"Hi"});
});
Is that how you send data from server→client in a production/deploy environment? Is there a more practical solution to it? Given that pug code is way too different from HTML (for example). Thanks and sorry for my english.
In a MEAN stack, you would use Express as the backend API and pass JSON data to the frontend, which could be Angular, React, Vue, etc.
For templating with Express, this should get you started. Let us know if this helps :)

Mimicking the features of node-webkit using a client and a server

I'm trying to find out whether it's possible to invoke node.js functions from a web page. Is there any way to make node.js functions accessible from Google Chrome (so that they are run on the node.js server), as shown here?
(I'm aware that it's possible to do this using node-webkit (a non-standard Chromium implementation) without modifying the code, but I'd prefer to do this using an unmodified browser, which will require the code shown below to be modified in some way.)
<html>
<body>
<script type = "text/javascript">
var exec = require('child_process').exec; //node.js function
</script>
<p onclick = "exec('firefox')">
Click here to launch the Firefox web browser.
</p>
</body>
</html>
No, this is not possible, for clear security reasons.
You only have available to you what the browser gives you. node-webkit is the closest thing available, and does not meet your requirements.
NW has own method like node exec :
var gui = require('nw.gui');
gui.Shell.openItem('firefox', ,function(error, stdout, stderr) { });

Resources