web page going blank after clicking submit button with post method - html

I wanted to create a save feature for my flashcard app. The solution I thought of first would be to save details about every card added, so on start the app could retrieve all of that data and format the flashcards the way you left them. I set up a node express js server, but when I post from the form, the page goes blank. However, the data is posted which I just have console logging to the node server. How can I make the page not go blank and just stay on index html and function normally?
NodeJS Server:
const bodyParser = require("body-parser");
const fs = require("fs")
const app = express();
let urlencodedParser = bodyParser.urlencoded({ extended: false });
app.use(express.json());
app.use(express.static("public"));
app.listen(3000, () => {
console.log("Server Started");
})
app.post("/", urlencodedParser, (req, res) => {
//add data to json
console.log(req.body);
res.end();
//then respond by running function AddFlashCard(event)
})
HTML FORM CODE:
<form id="form-container" method="post">
<div class="justify-container">
<div class="formItem" id="box1">
<label for="card-title-input" class="label" id="card-title-label">Card Title:</label>
<input type="text" name="title" id="card-title-input">
</div>
<div class="formItem" id="box2">
<label for="card-front-input" class="label">Card Front:</label>
<textarea name="front" id="card-front-input" cols="30" rows="5" maxlength="160"></textarea>
</div>
<div class="formItem" id="box3">
<label for="card-back-input" class="label">Card Back:</label>
<textarea name="back" id="card-back-input" cols="30" rows="5" maxlength="160"></textarea>
</div>
<div class="formItem" id="box4">
<button type="submit" id="submit">Add Card</button>
</div>
</div>
</form>
After clicking my submit button, page goes blank, and node server outputs as an example,
[Object: null prototype] {
title: 'Title',
front: 'Front',
back: 'Back'
}
This is just the first step of it and not supposed to be fully functional given this code ofcourse, I would just like to start with getting this example data sent with from the form to the server and the page not going blank and functioning otherwise normally.

remove body-parser use only express.json()

Related

Trying to read a file from html but getting undefined in nodejs

app.post('/addimage', upload.single('image'), function(request, response){
console.log(request.body)
const body = request.file
console.log(body)
response.redirect('/image')
})
var storage = multer.memoryStorage()
var upload = multer({ storage: storage })
<div class="form-group">
<label for="image">Choose a image</label>
<input type="file" class="form-control-file" id="image" name="image">
</div>
First is the nodejs code and second part is the html form. The request.body returns the image file name but when i do the request.file(s) its just undefined. Ive tried
Solved needed to add enctype="multipart/form-data" in the form. Should have posted the full form for better help. Sorry

How to send html form data to another web server via a button click

I have two web servers. One running my front-end (example.com), one running my back-end (api.example.com).
On my front-end (example.com) I have this code which is a simple html website that has a form, with an input field and a button. When I click the button I'd like to get that data and send it to the back-end (api.example.com). For example, I put 'nathan' in the username field of the front end and click the button. I want it to send me to api.example.com/sendcode?username=nathan
I currently have this code, but the button is keeping me on the same website, instead of doing to a completely different url:
<form class="login100-form validate-form flex-sb flex-w" action="api.example.com" method="POST">
<span class="login100-form-title p-b-51">
Request for a code
</span>
<div class="wrap-input100 validate-input m-b-16" data-validate = "Username is required">
<input class="input100" type="text" name="username" placeholder="Username">
<span class="focus-input100"></span>
</div>
<div class="container-login100-form-btn m-t-17">
<button class="login100-form-btn">
Send code
</button>
</div>
<div class="flex-sb-m w-full p-t-3 p-b-24">
<div class="contact100-form-checkbox">
</div>
</div>
</form>
With this code it's sending me to 'example.com/api.example.com?username=nathan' How would I fix this, would like to keep the two completely different?
You need a fully qualified URL with protocol - preferably https, as in action="https://api.example.com/sendcode"
Please search for AJAX and your server process. Alternatively use fetch
const username = document.querySelector("[name= username]").value;
fetch('https://api.example.com/sendcode?username='+encodeURIComponent(username))
.then(response => response.json())
.then(data => console.log(data));
To use Ajax, you need to grab the submit event
Here I use jQuery for speed of coding an example, just include <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> in the page to use it
$(".login100-form").on("submit", function(e) {
e.preventDefault(); // stop submit
$.post('https://api.example.com/sendcode',
{ data : $(this).serialize() }, // the form content in key=value format
function(response) {
console.log(response)
})
})
Change your form action to include http:// e.g.
<form class="login100-form validate-form flex-sb flex-w" action="http://api.example.com" method="POST">
There could be numerous methods depending upon scenarios but simplest of all which might expose data in querystring is sending a post request on button click through a simple javascript method.

How to send data to the server without refreshing the page in vuejs?

I'm doing a CRUD with vue-cli and nodejs on the server side. So I have a form like this
<template>
<div id="formRoot">
<div class="form" >
<form #submit.prevent="sendToTable" action="/create" method="post">
Name
<input type="text" v-model="row.name" name="name" />
Price
<input type="number" name="price" v-model="row.price" />
Description
<textarea v-model="row.description" rows="3" name="desc"/>
<input type="submit" id="button" value="SAVE" />
</form>
</div>
<form class="" action="create" method="post">
<input type="text" name="input">
<input type="submit" value="send">
</form>
</div>
</template>
<script>
export default{
data(){
return{
row: {
name: '',
price: '',
description: ''
}
}
},
methods: {
sendToTable() {
console.log(this.row);
this.$parent.addToTable(this.row);
}
}
}
</script>
the #submit.prevent is for avoid the page refreshing and of course I have a method named sendToTable.
in node I have this:
const path = require('path');
const morgan = require('morgan');
const app = express();
//middlewares
app.use(express.urlencoded({extended: false}));
app.use(express.static(path.resolve(__dirname, '../dist')));
app.use(morgan());
app.post('/create', (req, res) => {
console.log(req.body);
});
const port = 3000;
app.listen(port, () => {
console.log('server listening on port ' + port);
});
the problem is that the server cant get the post request, I think is because the #prevent.default property.
I tried sending a post request with postman and it works, so I'm sure the problem is in the frontend.
What should i do? How are actually coded those single page web apps that can send data to the server?
You need to actually post your form data via an HTTP request. You can use a library like Axios (very popular) or fetch (check the supported browsers list).
Another thing you appear to be doing is calling a method on this component's parent. That goes against Vue's one-way data flow and isn't optimal. The better solution is to have your component emit an event with the attached data.
For example (using fetch)
<form #submit.prevent="sendToTable" method="post" action="/create">
methods: {
async sendToTable ($event) {
const form = $event.target
// post form as a regular "submit" would
let res = await fetch(form.action, {
method: form.method,
body: new URLSearchParams(new FormData(form))
})
if (res.ok) {
// emit the "row-added" event to the parent
this.$emit('row-added', { ...this.row }) // using spread syntax to break references
} else {
// you might want to do something else here in case of an error
console.error(res)
}
}
}
and in your parent component (assuming the child component is named RowAdder)
<RowAdder #row-added="addToTable"/>

passing form data in a Google Cloud 'privileged environment'

I'm using Node.js on Google cloud with Firebase Realtime Database.
I can write and read data from server.js to the actual Firebase real-time database.
const express = require ('express');
const path = require('path');
var firebase = require("firebase-admin");
var serviceAccount = require("./srverKey.json");//path to key file
//Instantiate express
const app = express();
//Set URL routes
app.use('/static', express.static('public'))
app.get('/', function(req, res){
res.sendFile(path.join(__dirname, '/index.html'));
})
//Instantiate firebase Admin
firebase.initializeApp({
credential: firebase.credential.cert(serviceAccount),
databaseURL: "https://something.firebaseio.com"
});
// Get a database reference to our posts
var db = firebase.database();
//create a sample message
var message = {text: 'hello', timestamp: new Date().toString()};
var ref = firebase.database().ref().child('node-client');
var logsRef = ref.child('logs');
var messagesRef = ref.child('messages');
//below .push creates a new record with a new key
var messageRef = messagesRef.push(message);
logsRef.child(messageRef.key).set(message);
logsRef.orderByKey().limitToLast(1).on('child_added', function(snap){
console.log('added', snap.val());
});
logsRef.on('child_removed', function(snap) {
console.log('removed', snap.val());
});
ref.child('logs').on('child_changed', function(snap) {
console.log('changed', snap.val());
});
ref.child('logs').on('value', function(snap) {
console.log('value', snap.val());
});
<form>
<label for="userId">User ID</label><br>
<input type="text" name="userId" id="userId"><br>
<label for="firstName">First Name</label><br>
<input type="text" name="firstName" id="firstName"><br>
<label for="lastName">Last Name</label><br>
<input type="text" name="lastName" id="lastName"><br>
<label for="age">Age</label><br>
<input type="number" name="age" id="age"><br>
<button id="addBtn" class="btn waves-effect waves-light">Add</button>
<button id="updateBtn" class="btn waves-effect waves-light">Update</button>
<button id="removeBtn" class="btn waves-effect red darken-1">Remove</button>
</form>
However I can't figure out how the hell people pass values from index.html to server.js in order to store them in firebase.
When you connect from a privileged environment (google cloud) you use different code to connect than when from your own server therefore the examples under:
https://firebase.google.com/docs/samples/
are useless to me. They connect from public HTML javascript to the database where as in a 'privileged environment' you connect from the server-side script.
how do you read the from data from server.js?
How do you call a function to read the form from the html?
In say PHP you would post the form to a link.
What I'm looking for here is middleware called 'body parser'
npm install body-parser
I am having the same issue; however, I think your comment and answer get it correct: you have to have a POST method on form submit, and this route and method can be accommodated by Express in server.js. You can then pass this data to Google Cloud.

File not uploading properly

EDIT: Edited it using Mikhail's suggestion. Got closer to the solution
Hi I am trying to upload a JSON file using nodejs but for some reason it says my file is undefined. A file appears in my Public folder that contains the contents of the uploaded file however. I was wondering if someone would be able to help me out. Thanks
Here is the HTML
<form method="post" enctype="multipart/form-data" action="/file-upload">
<input type="file" name="theFile" >
<input type="submit" class = "submit">
</form>
EDIT: Here is the server.js
app.post('/testtwilio',upload.single('theFile'),function(req, res, next) {
console.log('FIRST TEST: ' + req.file);
});
Here is the JSON file
[{"name":"FIRST LAST","date":"12/22/2016","number":"7523924324"}]
Here is what is being logged
FIRST TEST: [object Object]
Change your JSON.stringify(req.files) to JSON.stringify(req.file)
Full code
HTML
<form id = "uploadForm" enctype = "multipart/form-data" action = "/api/file" method = "post">
<input type="file" name="userFile" />
<input type="submit" value="Upload File" name="submit">
</form>
JS
var express = require('express')
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
var app = express()
app.get('/',function(req,res){
res.sendFile(__dirname + "/index.html");
});
app.post('/api/file', upload.single('userFile'), function (req, res, next) {
console.log(JSON.stringify(req.file))
})
app.listen(3000,function(){
console.log("Working on port 3000");
});
Note:
File name which you use in multer.single() method should match name in input <input type="file" name="userFile" />
If you use the .single(...) method the file will be in req.file.