I've launched a server with Express and attached MongoDB to it. And I put link to app.js file that is used in HTML webpage, but Idk why, but server wants to load js file from localhost:3000, but not from my folder. Here's my project folder:
app
|_node_modules
|_www
|_app.js
|_index.html
|_index.js
|_user.js
|_package.json
|_package-lock.json
app.js file is empty, but index.html isn't
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" charset="utf-8"></script>
<script src="app.js" charset="utf-8"></script>
<meta charset="utf-8">
<style>
input {font-size: 30px}
</style>
<title></title>
</head>
<body>
<button onclick=hashGen()>GENERATE HASH</button>
<form action="/post" method="post">
<input type=text name=pass id=hash>
<input type=number name=pin>
<input type=submit value=submit />
</form>
</body>
</html>
And finally server script (index.js):
// Import modules
exp = require('express');
path = require('path');
parser = require('body-parser');
db = require('mongoose');
User = require('./user.js').User;
app = exp();
// Express & Mongoose params
app.listen(3000);
app.use(exp.static('public'));
app.use(parser.urlencoded({ extended: false }));
app.use(parser.json());
db.Promise = global.Promise;
db.connect("mongodb://localhost:27017/node-demo",{ useNewUrlParser: true });
// Load page
app.get('/',(req,res)=>{
res.sendFile(path.join(__dirname + '/www/main.html'));
})
// Take input & send to db
app.post('/post',(req,res)=>{
let data = new User(req.body);
data.save().then(item =>{
res.send(req.body.user + ' added.')
}).catch(err => {
res.status(400).send("unable to save to database");
});
})
Then I launched my server with nodemon index and it loaded, but with two errors:
GET http://localhost:3000/app.js 404 (Not Found)
localhost/:1 Refused to execute script from 'http://localhost:3000/app.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
Do u guys know what's wrong?
You mapped wrong root directory for your public/static files:
app.use(exp.static('public'));
Should be:
app.use(exp.static('www'));
Related
I can't make the section helper work as intended. The body of login.hbs was parsed normally, but the js section was never parsed. I have tried using helpers inside res.render() and put section() straight into engine() and it didn't work either
app.js
import express from "express"
import expressHbs from "express-handlebars"
const app = express();
app.use(express.urlencoded({ extended:true }));
app.engine('hbs', expressHbs.engine({
defaultLayout: 'main.hbs',
helpers: {
section(name, options) {
if (!this._sections)
this._sections = {};
this._sections[name] = options.fn(this);
return null;
},
},
}));
app.set('view engine','hbs');
app.set('views','./view');
app.get("/", (req, res) => {
res.render("login");
})
app.listen(3000, () => console.log("listening"));
main.hbs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
{{{body}}}
{{{_section.js}}}
</body>
</html>
login.hbs
<h1>Hello</h1>
{{#section "js"}}
<script>
console.log("hello world")
</script>
{{/section}}
Edit
I can't embed HTML either
login.hbs
<h1>Hello</h1>
{{#section "js"}}
<p>a paragraph</p>
{{/section}}
I tried to run it. The real reason why it is not rendering is because inside your main.hbs you need to have {{{_sections.js}}} inside the html body tags instead of just {{{_section.js}}} like you have it now. The script tag should run as well.
Sorry for the confusion with the previous answer.
The problem showing up when I click the button submit.The error coming out 404 not found and "Cannot POST/Index" in the website. Am I have logical problems on the code or problem that occur on the syntax. My program is doing without any http request, it's just a normal import express engine and integrate with html which I'm trying to do a basic post back function to express(server) and post the answer back to my angular html.
I'm trying to post the number back to the server for the calculation and doesn't know where is the error that make me could not doing Post Function. Please get the requirement file from me if the file that I uploaded is not completed.
app.component.html
In my HTML file do I need to add somethings for link the server.ts? Is there still any issue that I have to check on it?
<!doctype html>
<html lang="en">
<head>
<Title>Calculator</Title>
<meta charset="utf-8">
<title>Myapp</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
</head>
<body>
<h1 align="center">Angular Calculator</h1>
<div class="container">
<div class="card">
<div class="card-body">
<form action="index" method="POST">
<input type="number" name="num1" class="form-control" placeholder="Number">
<input type="number" name="num2" class="form-control" placeholder="Number">
<select ng-model="operator" name="operator">
<option>+</option>
<option>*</option>
<option>-</option>
<option>/</option>
</select>
<button type="submit">Submit</button>
</form>
<p>Calculation Of the number is :{{ result }} </p>
</div>
</div>
</div>
</body>
</html>
server.ts file
This is the by default server file that generate by npm which I'm not sure the syntax of code any problems for my first testing of addition functions.
import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import * as bodyParser from 'body-parser';
import * as express from 'express';
import {join} from 'path';
// Express server
const app = express();
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');
// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} = require('./dist/server/main');
// Our Universal express-engine (found # https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
bootstrap: AppServerModuleNgFactory,
providers: [
provideModuleMap(LAZY_MODULE_MAP)
]
}));
app.set('view engine', 'html');
app.set('views', DIST_FOLDER);
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
maxAge: '1y'
}));
// All regular routes use the Universal engine
app.get('*', (req, res) => {
res.render('/app.component.html', { req });
});
app.get('*', (req, res) => {
res.status(404).send('data requests are not supported');
});
//have body-parser is a piece of express middleware that reads a form's
//input and stores it as a javascript object accessible through
//can not to include body-parser but not to get the raw request, your body and header are not in the root object of request parameter
app.post('/',(req, res) => {
//var num1 = req.body.operator
var result=req.body;
console.log(req.body);
var operator = req.body.operator
if (operator == "+")
{
res.render('/app.component.html', {
result: parseInt(req.body.num1) + parseInt(req.body.num2),
});
}
})
// Start up the Node server
app.listen(PORT, () => {
console.log(`Node Express server listening on http://localhost:${PORT}`);
});
The following line implies you are posting to /index:
<form action="index" method="POST">
For posting to your express service (which is hosted on port 4000 and hence the URL is http://localhost:4000), you have to define a submit behavior on your button. Check this for reference.
I think the problem is you don't include
'angular-route.js'
in your client-side code
you can't post to index <form action="index" method="POST">.
you need a server side file. like: <form action="form_process.php" method="POST">
I am a complete beginner to handlebars and am trying to modify the simple handlebars template taken from the example on glitch.com
I would like to be able to link between .hbs files as I would link between .html files but when I try however I am given the message cannot GET followed by whatever file I give to it.
Here is a grab of my overall structure for ref;
Here is the index.hbs files I am working with
<!DOCTYPE html>
<html>
{{> head }}
<body>
Link to second page
</body>
</html>
Which I would like to link to (for example) this secondpage.hbs file;
<!DOCTYPE html>
<html>
{{> head }}
<body>
Link back to index
</body>
</html>
Here is the code in my server.js file
// Generic node.js express init:
const express = require('express');
const app = express();
app.use(express.static('public'));
const hbs = require('hbs');
hbs.registerPartials(__dirname + '/views/partials/');
app.set('view engine', 'hbs');
app.set('views', __dirname + '/views');
app.get("/", (request, response) => {
let dt = new Date();
let data = {
projectName: process.env.PROJECT_DOMAIN,
luckyNumber: Math.floor(Math.random()*1000),
serverTime: new Date(),
ip: (request.headers["x-forwarded-for"]||"").split(",")[0]
};
data.json = JSON.stringify(data, null, 2);
response.render('index', data);
});
let listener = app.listen(process.env.PORT, () => {
console.log('Your app is listening on port ' + listener.address().port);
});
and the code in my watch.json
{
"install": {
"include": [
"^package\\.json$",
"^\\.env$"
]
},
"restart": {
"exclude": [
"^public/",
"^dist/"
],
"include": [
"\\.js$",
"\\.hbs$",
"\\.json"
]
},
"throttle": 100
}
If any of the details of the other files is necessary to assist let me know and I can provide.
I appreciate I am probably thinking about this in the wrong way, I have looked at handlebars in more detail and experimented with helpers etc. but it seems overly complicated for what I am trying to achieve, I thought you could write basic html within an hbs file? I am looking for the most straightforward, generic solution to the problem of linking between views in handlebars.
FWIW I want to use handlebars in a pretty simple fashion, basically just looking to have the equivalent of php includes using partials instead, so if there is a better way to approach the creation of the app with that in mind I would be grateful for advice.
Your code looks alright. What is the problem exactly? When you add {{> head}} partial to the index.hbs doesn't it render properly?
EDIT:
Okay, you have mainly 2 problems with your code:
You have no route defined on express linking to your /secondpage endpoint.
You are trying to link to a file Link instead of linking to an URL endpoint Link.
To fix your code you would have to define the endpoint linking to the handlebars file, so you need to change your server.js file to something like this.
const express = require('express');
const hbs = require('hbs');
const app = express();
app.use(express.static('public'));
app.set('view engine', 'hbs');
app.set('views', __dirname + '/views');
hbs.registerPartials(__dirname + '/views/partials/');
// 1st Page Route (URL Endpoint)
app.get('/', (request, response) => {
const data = {
projectName: process.env.PROJECT_DOMAIN,
luckyNumber: Math.floor(Math.random() * 1000),
serverTime: new Date(),
ip: (request.headers['x-forwarded-for'] || '').split(',')[0],
};
data.json = JSON.stringify(data, null, 2);
response.render('index', data);
});
// 2nd Page Route (URL Endpoint)
app.get('/secondpage', (request, response) => {
response.render('secondpage');
});
const listener = app.listen(process.env.PORT, () => {
console.log('Your app is listening on port ' + listener.address().port);
});
And then you need to fix your HTML links to this on index.hbs:
<!DOCTYPE html>
<html>
{{> head }}
<body>
Link to second page
</body>
</html>
And this on secondpage.hbs:
<!DOCTYPE html>
<html>
{{> head }}
<body>
Link back to index
</body>
</html>
Hope this helps you.
Instead of using handlebars I used express-handlebars
Terminal: npm i express-handlebars
Handlebars is a Middleware and functions as a Twig (Template Engine) so for your server I'd suggest:
// Generic node.js express init:
const express = require('express');
const app = express();
app.use(express.static('public'));
const exphbs = require('express-handlebars');
app.set('views', __dirname + '/views');
// added this part
app.engine('.hbs', exphbs ({
defaultLayout: 'main',
layoutsDir: ('views', __dirname + 'layouts'),
partialsDir: ('views', __dirname 'partials'),
extname: '.hbs'
}));
app.set('view engine', 'hbs')
app.get("/", (request, response) => {
let dt = new Date();
let data = {
projectName: process.env.PROJECT_DOMAIN,
luckyNumber: Math.floor(Math.random()*1000),
serverTime: new Date(),
ip: (request.headers["x-forwarded-for"]||"").split(",")[0]
};
data.json = JSON.stringify(data, null, 2);
response.render('index', data);
});
let listener = app.listen(process.env.PORT, () => {
console.log('Your app is listening on port ' + listener.address().port);
});
By doing this, you should have a file in your layouts folder named main.hbs where you will have that dynamic approach you're looking for. Something that stays the same for all pages. I will insert here a suggestion, feel free to adapt for your code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- CUSTOM CSS -->
<link rel="stylesheet" href="/css/main.css">
</head>
<body>
{{> navigation }}
<main class="container p-5">
{{{ body }}}
</main>
</body>
</html>
Now when you create a navigation.hbs in your partials folder you will have the same frontend in all pages in the navigation. This is because we defined in the server.js our default template to be main.hbs. Whilst for your body, the triple hash ({{{}}}) inserts the components of the other .hbs files that you define. Don't forget to create a index.hbs file inside the views folder.
I learned the basics of hbs by following this tutorial (Note it's in Spanish). The tutorial produces this open-source project (which I am including in case it is useful).
I'm having trouble starting with polymer. The purpose is (simple) ; an Express server that serve my index.html and the index.html that serve my polymer element.
And my first problem is : How do I use node_moduldes and the require statement inside of my polymer element. I think I found some leads, like Browserify or RequireJS, but it seems complicated. (And browserify didnt work..).
Could someone provide me a simple way to use the node_modules in this polymer element ?
I'll start with my project structure.
And the file :
public/index.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="import" href="./bower_components/webcomponentsjs/webcomponents-lite.js">
<link rel="import" href="./elements/neito-photoresistor.html">
<title>Neito's Domotics</title>
</head>
<styl></style>
<body>
<neito-photoresistor></neito-photoresistor>
</body>
</html>
server/app.js
"use strict"
//require
var express = require('express'),
path = require('path');
//Conf const
const _port = 3000;
//Server
var app = express();
//Middleware
app.use(express.static(path.join(__dirname, '/..', 'public')));
//Routing
app.get('/', function (req, res){
res.sendFile('../public/index.html', {root: __dirname});
})
.listen(_port, function (){
console.log('Server listening on : '+_port);
});
and the polymer element him self (I know it is complete bullshit but still the require problem is here): public/elements/neito-resistor.html :
<!DOCTYPE html>
<link rel="import" href="./../bower_components/polymer/polymer.html">
<!-- I know I cannot use the script src="" tag to import my node_modules -->
<dom-module id="neito-photoresistor">
<template>
<style>
</style>
<span>Ambient luminosity = <span>{{lum_pct}}</span> %</span>
</template>
<script>
Polymer({
is: 'neito-photoresistor',
ready: function() {
var mcp = require('mcp3008.js'),//I know that this line cause problem
can = new mcp();
},
properties: {
lum_pct: {
type: Number,
notify: true,
reflectToAttribute: true,
observer: '_getValueLumPct'
}
},
_getValueLumPct()
{
lum_pct = can.poll(0, 1000, function(value){
console.log('Luminosite ambiante = '+(100-((value/1024)*100))+' % ('+value+')');
return 100-((value/1024)*100);
});
}
});
</script>
</dom-module>
I've been building an isomorphic react app using node-jsx, browserify, reactify, etc. My code runs fine on the server, and components are mounted and rendered correctly. However, the react function doesn't seem to work, for instance, the handleClick function does not recognize alert(), or console.log() never prints out expected result on neither the server nor the client side console. Can anyone identify what's going on here?
UPDATE: Another thing I want to point out is, when I run the server and go to the browser, in the browser console(used chrome dev tool) I typed "window.React", it actually returned the React object. But console.log still doesn't do anything for click handler function.
views/index.ejs
<!doctype html>
<html>
<head>
<title>Shortened URL Generator</title>
<link href='/style.css' rel="stylesheet">
<link href="css/griddle.css" rel="stylesheet" />
</head>
<body>
<h1 id="main-title">Welcome to Shortened URL Generator</h1>
<div id="react-main-mount">
<%- reactOutput %>
</div>
<!-- comment out main.js to see server side only rendering -->
<script src="https://fb.me/react-with-addons-0.14.3.min.js"></script>
<script src="https://fb.me/react-dom-0.14.3.min.js"></script>
<script src="/main.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script src="//fb.me/JSXTransformer-0.12.0.js"></script>
<script type="text/javascript" src="scripts/griddle.js"></script>
</body>
</html>
routes/routes.js
var React = require('react/addons'),
ReactApp = React.createFactory(require('../components/ReactApp'));
module.exports = function(app) {
var storeUrls = {
"fb.com": "facebook.com"
};
app.get('/', function(req, res){
// React.renderToString takes your component
// and generates the markup
var reactHtml = React.renderToString(ReactApp({}));
// Output html rendered by react
// console.log(myAppHtml);
res.render('index.ejs', {reactOutput: reactHtml});
});
app.get('/:routeParam', function(req, res){
});
};
app/components/ReactApp.js
var TableComponent = require('./TableComponent');
var React = require('react/addons');
var urls = require('./url');
var Griddle = React.createFactory(require('griddle-react'));
var ReactApp = React.createClass({
componentDidMount: function () {
console.log("yes");
},
handleClick: function() {
// this.setState({liked: !this.state.liked});
var longUrl = this.refs.inputUrl;
urls.push({
"original url": longUrl,
"shortened url": "/"
})
console.log(longurl);
},
render: function () {
return (
<div>
<div id="form">
<form>
<section>Paste your long url here</section>
<input ref="inputUrl" value={this.props.value} type="text" placeholder="http://...." />
<button onclick={this.handleClick} type="submit" value="Submit">Shorten URL</button>
</form>
</div>
<div id="table-area">
<TableComponent />
</div>
</div>
)
}
});
module.exports = ReactApp;
app/main.js
var React = require('react/addons');
var ReactApp = require('./components/ReactApp');
var TableComponent = require('./components/TableComponent');
var mountNode = document.getElementById('react-main-mount');
var mountTable= document.getElementById('table-area');
React.render(new ReactApp({}), mountNode);
React.render(new TableComponent({}), mountTable);
server.js
var express = require('express'),
path = require('path'),
app = express(),
port = 5000,
bodyParser = require('body-parser');
require('node-jsx').install();
// Include static assets. Not advised for production
app.use(express.static(path.join(__dirname, 'public')));
// Set view path
app.set('views', path.join(__dirname, 'views'));
// set up ejs for templating. You can use whatever
app.set('view engine', 'ejs');
// Set up Routes for the application
require('./app/routes/routes.js')(app);
//Route not found -- Set 404
app.get('*', function(req, res) {
res.json({
'route': 'Sorry this page does not exist!'
});
});
app.listen(port);
console.log('Server is Up and Running at Port : ' + port);
Gulpfile.js
var gulp = require('gulp');
var source = require('vinyl-source-stream'),
browserify = require('browserify');
gulp.task('scripts', function(){
return browserify({
transform: [ 'reactify' ],
entries: 'app/main.js'
})
.bundle()
.pipe(source('main.js'))
.pipe(gulp.dest('./public/'));
});
gulp.task('default', ['scripts']);
document.getElementById('react-main-mount'); returns null if your script runs before that element is loaded in html.
What you should do is either include your script before the closing tag </body>, or run ReactDOM.render after DOMContentLoaded.
It can be a simple modification to your existing code:
if (typeof window !== 'undefined) {
window.React = require('react');
}
Do that for whatever you want make available globally, usually you'll want to do the same for ReactDOM too so you can call render directly in a html file. It's not usually recommended though. You might want to use the standalone downloads from React Downloads.
So I realized it has something to do with React.render in the main.js file. instead of
React.render(new ReactApp({}), mountNode);
it should be
React.render(<ReactApp/>, document.getElementById('react-main-mount'));
In this case, TableComponent does not need to be rendered, also require React without using the addon.
It works now. Thanks for everyone's help!