Trying to send data from a html form and Node.js - javascript

I'm trying just to practice manipulating data from a static html page to Node.Js without using Angular, React or other framework libraries. I've installed all of my dependencies and node is serving my index.html, however, I can't seem to get my post method to work. I can't get it to even console.log anything. I've looked at the other stack overflow issues and the documents but can't seem to figure out the issue.
Here is my code and file structure.
HTML:
<form id="citySearchForm" action="http://127.0.0.1:3000/getcity" method="POST">
<div>
<p>Choose a city:</p>
<input type="text" placeholder="Enter a city" id="getCitiesInput" name="city"></input>
<input type="submit" value="submit">
</div>
<div id="weather"></div>
<p><span id="temp"></span></p>
<p><span id="wind"></span></p>
</form>
node.js:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false});
app.use(express.static('public'));
app.get('/index.html', function(req, res){
res.sendFile(_dirname + "/" + "index.html");
})
app.post('/getcity', urlencodedParser, function(req, res){
response = { city : req.body.city };
console.log(response);
res.end(JSON.stringify(response));
})
app.listen(3000, function() { console.log('listening')});
json:
{
"name": "basic_weather_api",
"version": "1.0.0",
"description": "Just a basic api call",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.16.0",
"express": "^4.14.1"
}
}

I have verified your code and it works perfectly fine.
On submit with city = Test, I see this Json response in browser : {"city":"Test"}
Also, I am albe to see your log statement printed. But remember your console.log() statement is part of the node.js server code, which means your log statement will be printed in server log and not in the browser console. If you are running your node server from terminal using node server.js you will see your log printed in the terminal.
If you have modified version of dependencies multiple time, delete node_modules directory and try to run npm install again.

Related

Firebase from Centos and express as backend not working

I have decided to use firebase as a backend for authentication and basic form information with firestore.
In the past I've used this express api in cloud functions to do this, and am basing this new setup off of that. But I'm looking to just use it on a Vultr Centos server instead, to put with the rest of my api, and just make everything easier for now as i don't want to overcomplicate things (until later :P).
Now - I've just cloned this repo onto my server, and I want to test it with postman, and i'm having trouble just accessing it.
I'm not sure how to solve the issue and if anyone could point me in the right direction that would make my life so much easier!
here is the index file and the package json file currently. I've created the server.listen to try and make it work at the moment.
const functions = require("firebase-functions");
const app = require("express")();
const FBAuth = require("./util/fbAuth");
const server = require('http').createServer(app);
const cors = require("cors");
//This was recently added to try and make it all work easier!
server.listen(port, ipaddress, () => {
});
app.use(cors());
const { db } = require("./util/admin");
const {
getAllWorkflows,
...
} = require("./handlers/workflow");
const {
signup,
login,
uploadImage,
addUserDetails,
getAuthenticatedUser,
getUserDetails
} = require("./handlers/users");
// Workflow Routes
app.get("/Workflows", getAllWorkflows);
...
// user route
app.post("/user", FBAuth, addUserDetails);
app.post("/user/image", FBAuth, uploadImage);
...
// cloud functions are better than firebase library because of load time.
exports.api = functions.https.onRequest(app);
here is the package.json file.
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "10"
},
"dependencies": {
"busboy": "^0.3.1",
"cors": "^2.8.5",
"express": "^4.17.1",
"firebase": "^7.21.1",
"firebase-admin": "^8.9.0",
"firebase-functions": "^3.11.0",
"firebase-tools": "^7.11.0"
},
"devDependencies": {
"firebase-functions-test": "^0.1.6",
"node-gyp": "^5.0.7"
},
"private": true
}
With the backend i am fixing up, I use this sort of workthrough (if it helps!), which I am replacing with firebase stuff above - if that makes sense. It works currently, is accessible for signup and login functionality, the key part for me is just using firebase and firestore with it.
const config = require('../../config');
const express = require('express');
const app = express();
const server = require('http').createServer(app);
.....
server.listen(config.serverParams.port, config.serverParams.address, () => {
console.log(`Server running at http://${server.address().address}:${server.address().port}`);
});
....
app.use((req,res,next)=>{
//can reaplce * with website we want to allow access
res.header('Access-Control-Allow-Origin', 'https://moodmap.app/stats');
next();
});
....
io.on('connection', socket => {
socket.use((packet, next) => {
.....
});
});
Really appreciate any guidance on this matter!
Firebase and firestore seems like a nice way to avoid reinventing the wheel, if only i could simply type npm start, and begin testing with postman the underlying functionality :s
The API is based off another side project i did, which is largely here for those interested in exploring it more.
https://github.com/Hewlbern/LightSpeed/tree/master/sigops
Very happy to just use the easiest way forward - I don't want to have any of the libraries on the client side though, as i want to make my front end super efficient. Thanks!
Cloud Functions does not allow you to listen on any ports in order to receive requests. It automatically handles incoming connections using the URL automatically provided during deployment. All incoming requests to that URL are routed to your function callback defined by the exported function built by functions.https.onRequest().
If you require the ability to listen to specific ports, Cloud Functions is not the right product for your use case. Cloud Functions can not be deployed on custom servers - it only works on infrastructure provided by Google.

Node.JS, ExpressJS, React and HTML JSON rendering

I am a beginner in web dev and I am developping a web app using firstly Node.JS to scrape restaurants informations from two websites (Maitres Restaurateurs and Guide Michelin), then ExpressJS to begin the app. I use res.sendFile() function to display my HTML page then res.json() to send a JSON file in the HTML page.
First, here is my work dir (It's a mess):
src
├server.js
├index.html
├server-side
├bib.js
├jsx
├react.jsx
server.js code (where i get in the listFinal variable a JSON object with all my restaurants informations scraped with puppeteer on the two website. It was done thanks to bib.js):
const express = require('express');
const app = new express();
const bib = require('./server-side/bib');
var listFinal = bib.get();
app.get('/', function (req, res) {
res.sendFile('./index.html', {root: __dirname});
res.send(listFinal);
});
app.listen(8000, function () {
console.log('Example app listening on port 8000!');
});
The server is working good. However none of my HTML or my React code is working (I'm completly new to React). The only thing displayed on my HTML is my huge JSON stored in the variable listFinal. The list has a length (or size) of 50 and here is its structure:
[{"name": "Saperlipopette ",
"url": "www.saperlipopette1.fr",
"address": "9 place du Théâtre, Puteaux, 92800, France",
"price_style": "36 - 65 EUR • Cuisine moderne",
"phone": "+33 1 41 37 00 00"},
...]
My index.html code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Session 3 Work - Axel Joly</title>
<meta name="description" content="Bib gourmand + Maitre restaurateur scrappeur">
<meta name="author" content="Axel Joly">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<h1>Welcome to the Bib Gourmand and Maitre Restaurateur list (made by Axel Joly):</h1>
<div id="root">
<ul id="list-rest">
</ul>
</div>
<script src="./jsx/react.jsx"></script>
</body>
</html>
And my react.jsx code:
var React = require('react');
var ReactDOM = require('react-dom');
export class Hello extends React.Component {
render() {
return (
<h1>Welcome to React!!</h1>
);
}
}
ReactDOM.render(<Hello />, document.getElementById('root'));
As explained before, none of them are displayed.
When I run node server.js and go to localhost:8000/, I've got this:
As you can see, there is no <h1> header rendered, both normally displayed with React and HTML. Also, I don't know how to "retrive" my variable listFinal in the HTML to render it as a li with <ul> and <li> tags.
As mentioned in the above comment you are trying to run React via a single JSX file, what you want to do is to create a react app via npx create-react-app client which would send the request to your server-side code. So, i have modified your code and what i have done is used concurrenlty to run both the server-side and client-side at the same time, this is done by changing the package.json of the server-side.
"scripts": {
"build": "next build",
"start": "node index.js",
"server": "node index.js",
"client": "npm start --prefix client",
"clientinstall": "npm install --prefix client",
"dev": "concurrently \"npm run server\" \"npm run client\""
}
The Next thing you want to do is send a request from your client side to your side,you can send do this by using axios
GetData = async () => {
try {
let response = await Axios.get(`http://localhost:8000/`, {
crossdomain: true
});
console.log(response.data); // This would log the data received from your server
//Res of Code
you can check the working example here (I tried using codesandbox but i was experiencing some issues there so i uploaded it on Github instead)
so to run the run the project you would open your terminal and run the following commands
git clone https://github.com/AbdullahAbid87/APIExample.git
cd APIExample
npm i
cd client
npm i
cd ..
npm run dev
(Note: if the request to the server-side does not go through , then it is probably a CORS issue ,Although this might not be ideal but the simplest way to solve it would be to download a browser extension called CORS Everywhere that should solve it right away)
Hope this Helps

The script doesn't work after deploying a javascript app to heroku

I created a simple javascript app with mojs, an animation library, and wanted to deploy it to heroku. First, I tried to "heroku create" etc and deploy the original app to heroku - the app was accessible, but the script didn't work. Second, I tried to change an app that I made following the Node.js tutorial from heroku website, by inserting a script bootstrap tag
<script src="http://cdn.jsdelivr.net/mojs/latest/mo.min.js"></script>
<script src="myburstscript.js"></script>
copying the script I made to the folder of this app
var myBurst = new mojs.Burst({
count:10,
radius: {0 :150},
angle: {0 : 180},
children : {
//fill:{'red' : 'blue'},
fill: ['red', 'purple', 'blue', 'violet'],
duration : 1000,
radius: 10,
shape: 'polygon',
delay: 'stagger(50)'
}
});
document.addEventListener('click', function(e) {
myBurst.replay();
});
then running "npm install mojs", and, as usual,
git add .
git commit -m "somedumbsh*t"
git push heroku master
But it didn't play the animation it plays on my localhost. Logs show no errors. The rest, the html part of the page, works fine. Why?
Heroku needs some server, not only the client-side code.
If you cannot start your app with:
PORT=4446 npm start
and then access it on:
http://localhost:4446/
then you won't be able to host it on Heroku.
(I'm assuming that you're using Node as indicated by the tags in your question.) It's important that your app needs to actually use the port number provided in the PORT environment variable, not just a hardcoded port number.
For example if you put all your static files (HTML, client-site JavaScript, CSS, images etc.) in a directory called html then you can use a simple server like this, e.g. called server.js:
'use strict';
const path = require('path');
const express = require('express');
const app = express();
const port = process.env.PORT || 3338;
app.use('/', express.static(path.join(__dirname, 'html')));
app.listen(port, () => console.log(`Listening on http://localhost:${port}/`));
Example package.json:
{
"name": "your-name",
"version": "0.0.0",
"description": "Your description",
"scripts": {
"start": "node server.js",
},
"author": "Your details",
"license": "MIT",
"dependencies": {
"express": "^4.15.2",
}
}
See also this example that I posted on GitHub for a complete solution that even has a Deploy to Heroku button:
https://github.com/rsp/node-live-color
It is an example that was created for this answer:
Getting data from/writing data to localhost with Express
where you can find more details on why it was written like that.

Why is node.js not finding my HTML pages

I have a test directory C:\node_samples\hello_express set up:
I have a package.json file in the test directory:
{
"name": "hello_express",
"version": "0.0.0",
"description": "A simple web site",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Pieter Geerkens",
"license": "MIT",
"private": true,
"dependencies": {
"express": "4.13.4",
"formidable": "1.x"
}
}
I have node.js, express and formidable properly installed in a ../node_modules subdirectory (at least, success reported from the install.) by running this command from the test directory:
npm install
I have an app.js file located in the test directory:
var express = require('express');
var app = express();
var formidable = require('formidable');
app.use('/forms', express.static(__dirname + '/public'));
app.post('/SubmitHelloPost', function (request, response) {
if (request.method.toLowerCase() == 'post') {
// parse form data
var form = new formidable.IncomingForm();
form.parse(request, function (err, fields) {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.write('Hello ' + fields.userName + '!<br />');
response.end('Have a POST great day!');
console.log('Handled POST request from ' + fields.userName);
});
}
});
app.get('/SubmitHello', function (request, response) {
response.writeHead(200, { 'Content-Type': 'text/html' });
response.write('Hello ' + request.query.userName + '!<br />');
response.end('Have a great day!');
console.log('Handled GET request from ' + request.query.userName);
});
var port = 8081;
app.listen(port);
console.log('Listening on port: ' + port);
I open a command prompt and run node app as follows:
However when I attempt to run the test by navigating to either of:
http://localhost:8081/HelloForm.html
http://localhost:8081/HelloPost.html
I get an Error 404.
The html files are (HelloForm.html):
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<form method="get" action="/SubmitHello">
Enter Name: <input type="text" name="userName" autofocus />
<input type="submit" value="Submit" />
</form>
</body>
</html>
and (HelloPost.html*):
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<form method="post" action="/SubmitHelloPost">
Enter Name: <input type="text" name="userName" autofocus />
<input type="submit" value="Submit" />
</form>
</body>
</html>
I have no idea what is wrong. everything worked briefly after I first set it up, then stopped working.
I think your problem is caused by the following line:
app.use('/forms', express.static(__dirname + '/public'));
This tells Express that when it receives requests starting with /forms, it should map those to static files in the /public folder. From your directory structure, I think this is what you're trying to do:
app.use('/', express.static(__dirname));
(It's still a good idea to move your static files to a separate directory though. Right now, navigating to http://localhost:8081/app.js would return the raw server-side code, which you probably don't want to be readable from your client-side code.)
You should make a directory for those files (I'll use 'public' for this example). Then move the files you want to serve to it, and then change
app.use('/forms', express.static(__dirname + '/public'));
to
app.use('/', express.static(__dirname + '/public'));
The first argument is the server directory where clients access the files, which you want to be the root directory (i.e. '/'), and the second argument is where the files are stored. Usually you don't want to mix your public content (like html), with private content, like server logic, so you put it in a separate folder and only serve that content.
It looks like there are at least 2 problems.
Problem #1
You've mounted your static asset directory at the /forms path, meaning any static assets you want to retrieve will be found at http://localhost:8081/forms/SomeFileName. You are trying to locate them directly at http://localhost:8081/HelloForm.html, which won't work. If you want to get rid of the /forms part of the path entirely, then you can remove the path argument entirely from your static asset declaration:
app.use(express.static(__dirname + '/public'));
Problem #2
You don't have these files inside the public directory anyway. They're just sitting out in your root directory. Instead you want them to be inside a folder called public, so that your static asset declaration can find them. That's why it has the word public in it, like so:
app.use('/forms', express.static(__dirname + '/public'));
So instead, create a folder in the root directory called public and move both those files (HelloForm.html and HelloPost.html) into there.
Here are the Express docs on static file serving, which show you how it works in more detail.
However, I'm guessing that even though this will work to display those 2 files, this is probably not what you ultimately want to do. My guess is that you want to use the 2 routes you've defined to show these 2 pages. My recommendation would be to read up on using a View Engine like EJS to render dynamic views, and also read up on RESTful routing to determine how to name your routes.

Can't get response data with Oauth2/BaseCamp API

I am an "advanced beginner" with javascript API's so my needs maybe sophomoric, but after pounding my head against the wall all night appreciate any basic guidance you can provide. I am trying to authenticate an app using Oauth2 to hit my BaseCamp site.
I am using Grant Express and have registered my app successfully such that I received client_ID, client_secret and redirect uri. For the redirect uri I added a folder called "auth" but the only thing in it is an index.html file that is blank. So the redirect url is http://example.com/auth.
On my local machine I have created a directory called oauth and within it ran:
npm install express
npm install grant-express
I created a file app.js that looks like this:
var express = require('express')
, session = require('express-session')
var Grant = require('grant-express')
var config = {
server: {
protocol: "http",
host: "127.0.0.1:3000"
},
basecamp: {
key: "key_from_basecamp",
secret: "secret_from_basecamp",
callback: "/basecamp/callback"
}
}
var app = express()
app.use(session({secret:'grant',
resave: true,
saveUninitialized: true}))
app.use(new Grant(config))
app.get("/basecamp/callback", function (req, res) {
console.log(req.query)
res.end(JSON.stringify(req.query, null, 2))
})
app.listen(3000, function () {
console.log('Express server listening on port ' + 3000)
})
The package.json file looks like this:
{
"name": "auth",
"version": "1.0.0",
"description": "",
"main": "app.js",
"dependencies": {
"express": "^4.13.4",
"grant-express": "^3.6.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
I go to the terminal and enter node app.js and get the response: Express server listening on port 3000. All good right?
When I go to my browser and type in http://localhost:3000/connect/basecamp the url does redirect to: https://launchpad.37signals.com/authorization/new?client_id=client_id_from_basecamp&response_type=code&redirect_uri=http%3A%2F%2F127.0.0.1%3A3000%2Fconnect%2Fbasecamp%2Fcallback&type=web_server
but the page contains this error: :error: Provided redirect_uri is not approved
If I got to: http://localhost:3000/connect/basecamp/callback
I see this error (also in the console of the server) { error: { error: 'Grant: OAuth2 missing code parameter' } }
In the Basecamp API documentation it says:
Configure your OAuth 2 library with your client_id, client_secret, and redirect_uri. Tell it to use https://launchpad.37signals.com/authorization/new to request authorization and https://launchpad.37signals.com/authorization/token to get access tokens. What is "it" and how, exactly would I tell it to use these urls? Do I add these url's into my app.js file as objects? Or do I go into another file? Do I need to add something into http://example.com/auth?
Not sure where to go from here.... Many thanks for any assistance.
The problem was my redirect url. It should be
http://localhost:3000/connect/basecamp/callback On to new errors!

Categories