I read and tried samples like the one on https://github.com/frankhale/electron-with-express but still I don't understand how to convert an Express app into Electron
How can I use Electron with an existing Express application?
Take for example this Express application:
app.js
var express = require("express");
var app = express();
var request = require("request");
app.set("view engine", "ejs");
app.get("/", function(req, res) {
res.render("search");
});
app.get("/results", function(req, res){
var query = req.query.search;
var url = "https://yts.am/api/v2/list_movies.json?sort=seeds&limit=15&query_term='" + query + "'";
request(url, function(error, response, body){
var data = JSON.parse(body);
if(!error && response.statusCode == 200){
//res.send(data["data"]["movies"][0]["title"]);
res.render("results", {data: data});
//["movies"][0]["title"]
}
else
console.log(data);
});
});
app.listen(process.env.PORT, process.env.IP, function(){
console.log("IMDB server has started");
});
search.ejs
Search for a movie
<form action="results" method="GET">
<input type="text" placeholder="search term" name="search">
<input type="submit">
</form>
results.ejs
Results page
<ul>
<% data["data"]["movies"].forEach(function(movie){ %>
<li>
<strong><%= movie["title"]%></strong> - <%= movie["year"]%>
</li>
<% }) %>
</ul>
Search again
In the Electron main.js file, you should require your app.js file to start the Express application, then create a new instance of BrowserWindow and load the URL that your Express application is listening on.
Note that you'll either have to hard code the IP and PORT in Electron, or export them from Express and import them into the Electron main.js script.
./main.js
const { BrowserWindow, app } = require('electron')
require('./app.js')
let mainWindow = null
function main() {
mainWindow = new BrowserWindow()
mainWindow.loadURL(`http://localhost:3000/`)
mainWindow.on('close', event => {
mainWindow = null
})
}
app.on('ready', main)
./package.json
{
"name": "your-app-name",
"version": "1.0.0",
"description": "A description of your application",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"repository": "https://github.com/link/to/repo",
"keywords": [ "some","keywords" ],
"author": "You",
"license": "Your License",
"dependencies": {
"ejs": "^2.6.1", // required for your specific example where `ejs` package is used
"electron": "^3.0.9",
"express": "^4.16.4"
}
}
Then you'll want to make sure that the node_modules directory is in the same directory as main.js and package.json.
Finally, you can start your Express/Electron application using:
> npm start
If your Express application is not in the same directory as Electron, you will have to set the views directory for express accordingly:
app.js
var path = require('path')
var request = require("request");
var express = require("express");
var app = express();
app.set('views', path.join(__dirname, '/views'));
...
Where /views is a directory relative to app.js that contains your views.
Related
I am trying to implement a simple nodejs server with Express routing on A2 Shared Hosting service (once I get this working I can deploy a more complex app I have been working on).
The root returns a response (API Running) but I get a 503 error on any other routes I try setting up. I have gone through many postings but none seem to address my exact problem. The hosting service has an article suggesting using dynamic post assignment (which I have implemented).
If the root works but other routing doesn't, could this be something to do with EXPRESS (but again that works fine on localhost)?
The server.js file looks like this:
const express = require('express');
const snow = require('./routes/api/snow');
const app = express();
// Middle ware init
app.use(express.json({ extended: false }));
app.get('/snowshoe/', (req, res) => res.send('API Running'));
// Define routes
app.use('/snowshoe/api/snow', snow);
const server = app.listen(0, () => {
console.log('Example app listening at http://localhost:', server.address().port);
});
app.use(function (req, res, next) {
res.status(404).send("Sorry can't find that!")
})
and the /snowshoe/api/snow.js looks like this:
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => res.send('Snow plow required'));
module.exports = router;
Perhaps something with the Express routing?
package.json
{
"name": "snowshoe",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"start": "node server"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.2"
}
}
When you create a server (it's not just about node.js or express) you need to put a 4 digit number like 4000.
const port = 4000
const server = app.listen(port, () => {
console.log('Example app listening at http://localhost:${port}')
});
I am new to Node.JS and very curious to learn more about it, therefore I decided to do some exercises from a book.
The point which I am struggling is with the integration test.
I would like to have a crawler checking my application to see if the links are working fine. For that I am using the following code:
package.json
{
"main": "meadowlark.js",
"scripts": {
"test": "jest",
"lint": "eslint meadowlark.js lib"
},
"dependencies": {
"express": "^4.17.1",
"express3-handlebars": "^0.5.2"
},
"devDependencies": {
"eslint": "^5.15.3",
"jest": "^24.9.0",
"portfinder": "^1.0.20",
"puppeteer": "^1.13.0"
}
}
integration-tests/basic-navigation.test.js
const portfinder = require('portfinder')
const puppeteer = require('puppeteer')
const app = require('../meadowlark.js')
let server = null
let port = null
beforeEach(async () => {
port = await portfinder.getPortPromise()
server = app.listen(port)
})
afterEach(() => {
server.close()
})
test('home page links to about page', async () => {
const browser = await puppeteer.launch()
const page = await browser.newPage()
await page.goto(`http://localhost:${port}`)
await Promise.all([
page.waitForNavigation(),
page.click('[data-test-id="about"]'),
])
expect(page.url()).toBe(`http://localhost:${port}/about`)
await browser.close()
})
meadowlark.js
// Starting an express application
var express = require('express');
var app = express();
/* eslint-disable no-undef */
const port = process.env.PORT || 3000
/* eslint-enable no-undef */
// Set up handlebars view engine (Templating)
// Check the views folder for html skeleton and the respective
// handlebars
var handlebars = require('express3-handlebars')
.create({ defaultLayout:'main' });
app.engine('handlebars', handlebars.engine);
app.set('view engine', 'handlebars');
/* eslint-disable no-undef */
app.set('port', process.env.PORT || 3000);
/* eslint-enable no-undef */
const handlers = require('./lib/handlers')
// Function to generate the quote of the day
//const fortune = require('./lib/fortune')
// Homepage
app.get('/', handlers.home)
// About
app.get('/about', handlers.about);
// 404
app.use(handlers.notFound);
// 500
app.use(handlers.serverError)
// Binding to the port
if(require.main === module) {
app.listen(port, () => {
console.log( `Express started on http://localhost:${port}` +
'; press Ctrl-C to terminate.' )
})
} else {
module.exports = app
}
Error
meadowlark/integration-tests/basic-navigation.test.js:9
beforeEach(async () => {
^
ReferenceError: beforeEach is not defined
What am I missing/ doing wrong here?
You need to run your test through jest and not plain node otherwise all the globals defined by jest won't exist.
Example if you're using yarn:
yarn jest to run all tests it can find based on jest default settings (see documentation to customize)
yarn jest meadowlark/integration-tests/basic-navigation.test.js to only run your file
Hello i'm new to node js and i am trying send / pass post data to html but i can't seem to get it to work And was hoping maybe someone could point me in the right direction on how i can.
Server code:
const express = require("express");
const bodyParser = require('body-parser');
const app = express();
app.use(express.static("public"));
app.use(bodyParser.urlencoded({ extended: true }));
app.get("/", (request, response) => {
response.sendFile(__dirname + "/views/index.html");
});
app.post('/sendInfo', (req, res) => {
try {
console.log(`firstname: ${req.body.firstname} lastname: ${req.body.lastname}.`);
var firstName = req.body.firstname,
lastName = req.body.lastname;
res.sendFile(__dirname + "/views/info.html", { fistname: firstName, lastname: lastName });
} catch (e) {
console.error("error", e);
}
});
const listener = app.listen(process.env.PORT, () => {
console.log("Your app is listening on port " + listener.address().port);
});
views/info.html code:
<html>
<head>
<title>My Site title</title>
</head>
<body>
<h1><%= fistname %></h1>
<h1><%= lastname %></h1>
</body>
</html>
Looks like you are using the EJS template engine. So, there are a number of things that are missing in your code.
You need to tell express that you are using EJS at the template engine
The view must have an extension of .ejs not .html
You should be using res.render() and pass in the template name and the JSON data which will be used in the template
Set up a Node.js project using npm init -y, then run npm install express ejs, then create the app.js file (code given below) and finally create the views/index.ejs file (code given below). The views directory should be at the same level as your node_modules directory.
// app.js
const express = require('express');
const bodyParser = require('body-parser');
const port = process.env.PORT || 3006;
const app = express();
app.use(express.static(__dirname + '/build'));
app.use(express.json())
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json({ extended: true }));
app.set('view engine', 'ejs');
app.get('/fn/:first_name/ln/:last_name', (req, res) => {
res.render('index', {
first_name: req.params.first_name,
last_name: req.params.last_name
});
});
app.listen(port, () => {
console.log(`App listening on port ${port}`);
});
// views/index.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>First name is <%= first_name %></div>
<div>Last name is <%= last_name %></div>
</body>
</html>
Your package.json file must look something like this, use the start script
{
"name": "node-template",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node app.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"ejs": "^3.1.5",
"express": "^4.17.1"
}
}
Run the app using npm start
Finally, open up a browser and hit http://localhost:3006/fn/John/ln/Doe
If all goes well you will see an html rendered in the browser like this...
First name is John
Last name is Doe
Output:
Good luck.
Note: For the sake of simplicity I used GET instead of POST and used path params instead of request body. But the template engine works the same way.
I try to upload a file to a server using express.js and multer. I cannot get it work, even with a very simple code, it keeps displying the same error :
"TypeError: Cannot read property 'name' of undefined"
I suspect I make some really stupid mistake, yet I cannot find out what's the problem. Thank you very much for your help !
index.html :
<!doctype html>
<html>
<head>
<title>File upload test</title>
</head>
<body>
<form id="uploadform" method="post" action="/upload" enctype="multipart/form-data">
<p><input type="file" name="img"></p>
<p><input id="submit_upload" type="submit" value="Submit"></p>
</form>
</body>
</html>
and on the server side (server.js)
var express = require('express');
var app = express();
var multer = require('multer');
var upload = multer({ dest: 'uploads/' })
app.get('/', function(req, res){
res.sendfile(__dirname + '/client/index.html');
});
app.post('/upload', upload.single('img'), function (req, res) {
//var form_description = req.body.description;
console.log(req.files.name);
// insert operations into database get placed here
res.redirect('/');
});
package.json :
{
"name": "upload-example",
"version": "0.0.0",
"description": "A file upload example",
"main": "server.js",
"repository": "",
"author": "",
"dependencies": {
"async": "~0.2.8",
"express": "^3.2.6",
"multer": "^1.1.0",
"socket.io": "~0.9.14"
}
}
1) You configure multer to accept single file, and single file will be stored in req.file.
2) Original filename stored in req.file.originalname.
3) Temp filename stored in req.file.filename.
I am trying to learn the MEAN stack along with Swig templates. I’m coding from scratch, as I tried a MEAN framework but it generated a lot of files and it was too much for me to begin with.
Currently my Swig template index.html does not render the HTML. This is the output I am getting:
{% include 'header.html' %}
<br>Welcome to my test website
where as I am expecting following
This is coming from Header
<br>Welcome to my test website
Why is it not rendering?
Following is my folder structure:
--config
-config.js
--node_modules
-* //modules installed via npm link
--public
-header.html
-index.html
-package.json
-routes.js
-server.js
Below is the content of each file
config.js
var port = process.env.PORT || 8080;
module.exports = {
dburl: 'mongodb://localhost/test',
port: port,
templateEngine: 'swig'
}
header.html
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p> This is coming from Header</p>
index.html
{% include 'header.html' %}
<p>Welcome to my test website</p>
</body>
package.json
{
"name": "test",
"version": "0.0.1",
"author": "Rukmaj Chandavar",
"dependencies": {
"express": "*",
"mongoose": "*",
"angular": "*",
"swig": "*",
"consolidate": "*"
}
}
routes.js
module.exports = function(app){
app.get('*',function(req, res){
res.send('index.html');
});
}
server.js
var express = require("express");
var app = express();
var mongoose = require("mongoose");
var config = require('./config/config');
var swig = require('swig');
var cons = require('consolidate');
mongoose.connect(config.dburl);
app.use(express.static(__dirname + '/public'));
app.set('views', __dirname + '/public');
app.engine('html', cons.swig);
app.set('view engine', 'html');
require('./routes') (app);
app.listen(config.port);
console.log('MeriDawat running on port ' + config.port)
Following are the version numbers of installed node modules
angular#1.2.18
consolidate#0.10.0
express#4.4.3
mongoose#3.8.12
passport#0.2.0
swig#1.3.2
I would appreciate any help in troubleshooting this to help me move forward. Thanks in advance.
I think this is the offending line, in routes.js:
res.send('index.html');
res.send() just sends the contents of the file back in the HTTP response.
To render a template and send the rendered results back, you want res.render() instead:
res.render('index.html')