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.
Related
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()
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
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"/>
I am building a very simple ServiceStack website using the built-in SS Razor, Auth, and Fluent validation. I've set up a simple login page, but if there is any sort of failure, I'm shown the SS Snapshot of Authenticate generated by ServiceStack page.
login.cshtml
<form action="#(new Authenticate() { provider = "credentials" }.ToPostUrl())" method="post">
<input type="text" name="username" />
<input type="password" name="password" />
<input type="hidden" name="continue" value="#(new Home().ToGetUrl())" />
</form>
AppHost.cs (Configure snippet)
TimeSpan slidingExpiry = TimeSpan.FromMinutes(60);
var authProvider = new CredentialsAuthProvider()
{
SessionExpiry = slidingExpiry
};
AuthFeature authFeature = new AuthFeature(
() => new AuthUserSession(),
new IAuthProvider[] { authProvider },
htmlRedirect: new Login().ToGetUrl()
);
authFeature.IncludeAssignRoleServices = false;
authFeature.IncludeRegistrationService = false;
authFeature.IncludeAuthMetadataProvider = false;
I'd like to be able to trap this and display a razor view with the errors, instead of being required to do an AJAX call to authenticate. How can I set up my website to show a razor view for authentication failures?
Following API First development and using Ajax is definitely the preferred approach for handling Fluent Validation errors.
This FORM POST's to the Authenticate Service which requires its own Razor Views in order to show a different HTML Representation. So you'd need to add Authenticate.cshtml or AuthenticateResponse.cshtml View Pages to handle the Response of the Authenticate Service.
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.