I have a (probably very stupid) question.
I have a form I submit to my nodeJS server with Express.
This works perfectly with text inputs and radiobuttons, but now I have to add a select.
The server does not give an error but the select is not parsed properly.
my code:
<select id="chooselang">
<option value="nl" name="language">NL</option>
<option value="en" name="language">EN</option>
</select>
and my server looks like this:
app.post('/settings', function(req, res){
// Fill JSON array with new settings
var myData = {
,name : req.body.name
,mail : req.body.email
,language : req.body.language
,location: req.body.location
}
// Write to JSON file
fs.writeFile(configfilepath, JSON.stringify(myData, null, 4), function(err) {
if(err) {
res.send(500);
console.log(err);
} else {
setTimeout(function () {
res.redirect('back');
}, 2000)
}
});
});
Could someone please tell me what I'm doing wrong?
Probably you will need to add a name attribute in your select and use that to capture the values.
Also, only one of the option values will be sent to the server, so there is no point in assigning name to each one of the options, if that was your intention.
Related
I am working on a reactjs project, and nodejs i have 3 routers to count the user comments, likes, asked questions, and I need to show to her/his profile the results if they asked a question, or if they comment on someone post, in case the user is completely new I want to show just (0)
how can I do it?
this is code for the server-side
// user likes counter
router.get("/likescounter/:id", async (req, res) => {
const id = req.params.id;
const likesCounter = await Likes.count({
where: { UserId: id },
});
res.json(likesCounter);
console.log("Likes counter in like", likesCounter);
});
and this is the client-code
axios
.get(`${targetServer}/like/likescounter/${id}`)
.then((res) => {
if (res.data) {
setLikesCounts(res.data);
console.log(res.data);
}
})
.catch((err) => {
console.log(err);
});
and finally, this is where I render the result in the UI
<span className="text-gray-700">
{likedCount}
</span>
also, this is how the UI looks like:
any sugesstion please?
Base on information from the comment section, I would presume that you want to show (0) if the data is falsy (undefined, null)
So you would need to make a nullish coalescing operator
First, make sure your state initialize like this:
const [likedCount, setLikedCount] = useState(0);
Then update your jsx:
<span className="text-gray-700">
{likedCount ?? '0'}
</span>
Or Logical OR if you also want to show 0 if it returns a falsy value
<span className="text-gray-700">
{likedCount || '0'}
</span>
An alternative for old browsers or no babel configured project:
<span className="text-gray-700">
{likedCount ? likedCount : '0'}
</span>
if likedCount === undefined or null it will show 0
I will show my code first in order to be clear.
router.get("/add", (req, res)=>{
res.render("user/add.ejs");
});
router.put("/add/pi", (req, res)=>{
if(condition){
//do something
}else{
res.redirect("/user/add");
//res.render("user/add.ejs", {error: "At least one field should be filled in order to submit the form", type: "form error","location": "form-container"});
}
});
Ejs:
<% if(error){ %>
<small id="personalinformationError" class="form-text text-danger"><%= error %></small>
<% }%>
I want to be able to render the ejs template with the object in the render() in the comment. I tried to render it like in the comment without redirect() and it shows an error whenever I mention the variable name. The error goes like variable is not defined.
Thank you in advance.
I am building a node.js,express.js and passport.js app. Once logged into the profile I ask the user to click a button “Get Location” to get the users location.
Profile.ejs
<form action="/testform" method="post" >
<div class="form-group">
<input type="text" class="form-control" id="latVal" placeholder="latitude">
<input type="text" class="form-control" id="longVal" placeholder="longitude">
</div>
<button type = "submit" class="btn btn-warning btn-sm">Save</button>
</form>
<button type = "submit" class="btn btn-warning btn-sm" onclick="getLocation()">Get Location</button>
onclick the getLocation() function is called which is located in mapCall.js
function getLocation()
…
//call to showLocation()
}
function showLocation(position) {
…
document.getElementById("latVal").value = latitude;
document.getElementById("longVal").value = longitude;
}
showLocation() sets the values in the form to the latitude (id="latVal") and longitude (id="longVal") returned from the API call. The values appear in the form field. From here I want to save these values to the users profile data in MongoDB which I try to achieve in routes.js by click of the “Save” button which triggers the function below
app.post('/testform', isLoggedIn, function(req, res) {
user.findById(req.user.id, function(err,user) {
if(!user) {
req.flash('error', 'No accound found');
return res.redirect('/profile');
}
user.location.latitude = req.body.latVal;
user.location.longitude = req.body.longVal;
user.save(function(err){
res.redirect('/profile');
});
});
});
When I console.log req.body.latVal and req.body.longVal the value for these variables is undefined. Nothing is saved in the db.
In server.js I have
var bodyParser = require('body-parser');
app.use(bodyParser());
Upon looking into proposed solutions to req.body returning undefined I tried
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
I didn’t think adding the two lines above would work because the value returned by the API is not in JSON format. This did not work. I checked the typeof for latitude and longitude and it is a number. I am not sure why req.body is not picking up the value.
My initial guess was that app.post tries to read the value before the API can return a value in which case req.body.latVal would read an empty field. I added the save button to test that theory which also proved wrong.
The closest thing I found to my issue is this which was never resolved.
Any guidance is highly appreciated or perhaps even a better way to accomplish this will be great. The reason I have the form fields populate is because I couldn't think of another way to send the values from the frontend to the backend for saving.
Add the name attribute to your inputs.
<input type="text" class="form-control" id="latVal" placeholder="latitude" name="latVal">
<input type="text" class="form-control" id="longVal" placeholder="longitude" name="longVal">
EDIT: (from the comment)
You can do an AJAX call to your server after the getLocation() call.
function getLocation() {
///you get the lat and long
showLocation(position)
saveLocation(latitude, longitude)
.then(function(resp){
//do something with resp
})
}
function saveLocation(latitude, longitude) {
//we have native fetch in newer browsers, so
return fetch("/testform", {
method: "POST",
headers: {
"Content-Type": "application/json; charset=utf-8", //if this doesn't work use the below one
// "Content-Type": "application/x-www-form-urlencoded",
},
body: JSON.stringify({latitude,longitude}), // body data type must match "Content-Type" header
})
.then(response => response.json());
}
This is just an outline of what you can do. Extend this code to your needs.
You are correct in most parts ,You just have to replace ID with name.that is the only way nodejs will be able to locate to your input field
So I'm using Nodejs, MongoDB and Reactjs
and I'm trying to Edit properties of projects.
I have multiple projects and when I want to edit properties of one I can't do it. We can access to properties inside inputs, we can see Title and Type but can't even delete, write, he access to properties by its ID but then I can't change it, I guess I have multiple problems here than.
I'll write here my server code, and my Edit/Update project page and a gif with an example when I say that I can't even change anything on inputs.
My server code:
//Render Edit Project Page byId
app.get('/dashboard/project/:id/edit', function(req, res){
let id = req.params.id;
Project.findById(id).exec((err, project) => {
if (err) {
console.log(err);
}
res.json(project);
});
}
//Update Projects Properties byId
app.put('/dashboard/project/:id/edit', function(req, res){
var id = req.params.id;
var project = {
title: req.body.title,
typeOfProduction: req.body.typeOfProduction
};
Project.findByIdAndUpdate(id, project, {new: true},
function(err){
if(err){
console.log(err);
}
res.json(project);
})
};
My React Component Edit Project Page
import React, { Component } from 'react';
import { NavLink } from 'react-router-dom';
import './EditProject.css';
class EditProject extends Component {
constructor(props){
super(props);
this.state = {
//project: {}
title: '',
typeOfProduction: ''
};
}
inputChangedHandler = (event) => {
const updatedProject = event.target.value;
}
componentDidMount() {
// console.log("PROPS " + JSON.stringify(this.props));
const { match: { params } } = this.props;
fetch(`/dashboard/project/${params.id}/edit`)
.then(response => { return response.json()
}).then(project => {
console.log(JSON.stringify(project));
this.setState({
//project: project
title: project.title,
typeOfProduction: project.typeOfProduction
})
})
}
render() {
return (
<div className="EditProject"> EDIT
<form method="POST" action="/dashboard/project/${params.id}/edit?_method=PUT">
<div className="form-group container">
<label className="form--title">Title</label>
<input type="text" className="form-control " value={this.state.title} name="title" ref="title" onChange={(event)=>this.inputChangedHandler(event)}/>
</div>
<div className="form-group container">
<label className="form--title">Type of Production</label>
<input type="text" className="form-control " value={this.state.typeOfProduction} name="typeOfProduction" ref="typeOfProduction" onChange={(event)=>this.inputChangedHandler(event)}/>
</div>
<div className="form-group container button">
<button type="submit" className="btn btn-default" value="Submit" onClcik={() => onsubmit(form)}>Update</button>
</div>
</form>
</div>
);
}
}
export default EditProject;
Erros that I have:
1- DeprecationWarning: collection.findAndModify is deprecated. Use findOneAndUpdate, findOneAndReplace or findOneAndDelete instead.
2- Inputs can't change
3- When click "Update" button:
I think your update override the entire object because you forgot the $set operator. This is the operator to change only the atributtes of an object and not the entire object replacing!
Example:
Model.update(query, { $set: { name: 'jason bourne' }}, options, callback)
First of all, concerning the deprecation warning, you need to change the method findAndModify (As I do not see it here, I guess you're using it elsewhere, or maybe one of the methods you use is calling it) by one of the suggested methods and change your code accordingly.
Then, you need to learn about React and controlled components : https://reactjs.org/docs/forms.html
You need to set the component's state in your onChange handler, such as :
this.setState({
title: event.target.value // or typeOfProduction, depending on wich element fired the event
});
This is called a controlled component in React.
Concerning the response body you get when clicking on Update button, this is actually what you asked for :
res.json(project);
returns the project variable as a JSON file, which is displayed on your screenshot.
See this question for more information about it : Proper way to return JSON using node or Express
Try replace "value" in input tag with "placeholder"
I use mongodb with collection structure as follows:
chatbot collection
{
"_id" : ObjectId("5a2f8edf84b906480af0d121"),
"botname" : "Welcome Chat",
"description" : "Welcome Chat",
"status" : "Inactive"
}
route.js
app.get('/cpanel/chat-bot/:id', function(req, res) {
if (req.session.user == null) {
res.redirect('/cpanel/login');
} else {
CB.getAllRecords().then(results => {
res.render('cpanel/chat-bot/:id', { udata : req.session.user, chatbot: results});
}).catch(err => {
res.sendStatus(500);
});
}
});
index.ejs
<ul class="menu-sidebar">
<% for(var i = 0; i < chatbot.length; i++) { %>
<li>
<span class="fa fa-circle-o"></span><%= chatbot[i].botname %>
</li>
<% } %>
</ul>
how to display data chatbot by id from mongodb? when I click url 1 (/cpanel/chat-bot/1) it will show data id 1 from mongodb, when I click url 2 (/cpanel/chat-bot/2) it will show data id 2 from mongodb? Thank you
When you configure a route like
app.get('/cpanel/chat-bot/:id', ...)
The :id part of the route says that you want to match any value for that part of the path and then Express will put whatever was matched into req.params.id. So, if you want to use that id value as part of your database query, you need to use req.params.id in your database query in order to select only the desired data from your database.
In addition, you do NOT use :id in the render path so remove it from here:
res.render('cpanel/chat-bot/:id', ...);
That should just be a path to your template file (whatever the filename of the template is):
res.render('cpanel/chat-bot', ...);
You don't disclose much about your data in the database so we can't really help with how you would use the req.params.id value to select the desired data from your database. I presume you would use it in a query of some sort.