how to get single value from input name field instead of array in NodeJS - node.js

I am trying to delete elements from the note list. when I try to match a single name to a list title, it shows an array of items.
i want to match
const input name ===day
and output should be "home" from input name field
but it show ["home","home","home","home"]
here is my delete form code:
<form action="/delete" method="POST">
<% for (let i=0; i<newListItems.length; i++) { %>
<div class="item">
<input type="checkbox" onChange="this.form.submit()" name="checkboxname" value="<%=newListItems[i]._id%>">
<p><%= newListItems[i].name %></p>
</div>
<input type="hidden" name="listName" value="<%= listTitle %>"></input>
<% } %>
</form>
app.js code:
app.post("/delete", function (req, res) {
const deleteItem = req.body.checkboxname
const listName = req.body.listName
console.log(listName)
if (listName === day) {
console.log("hello")
} else {
console.log("custome list value")
}
})

There is 4 hidden inputs rendered with same name listName.
So your request payload will be fulfilled with array of values from all of these inputs.
Move hidden input outside of PHP loop.
The point is to make one input with name='listName' instead of four

Related

if statement handlebars with passed 2 values

I'm making a site with handlebars and nodejs and I want to show a "message" (you can best compare them to tweets) only if the "message" is from a specific user.
For the if statement I used the following question asked on stackoverflow in the past: Logical operator in a handlebars.js {{#if}} conditional I'm passing through 2 variables: messages and username where username is a string and messages an array. I use message as |item| to get a specific place from the array. The username is stored in item.[0]. As I change the username in the value to "test" in line 3 of the hbs code so it would be {{#ifCond item.[0] "test"}} then it works, but not with the username passed through with the value.
Here's my handlebars code:
{{#if user}}
{{#each messages as |item|}}
{{#ifCond item.[0] username}}
<div class="card" style="width: 100%;">
<div class="card-body">
<h5 class="cardtitle">{{#key}}</h5>
<h6 class="card-subtitle mb-2 text-muted">{{item.[0]}}</h6>
<h6 class="card-subtitle mb-2 text-muted">{{item.[2]}}</h6>
<p class="card-text">{{item.[1]}}</p>
</div>
</div>
<p></p>
{{else}}
<p>{{item.[0]}}</p>
{{/ifCond}}
{{/each}}
{{/if}}
The node.js code to load the page:
router.get('/users',loggedIn,messages,(req, res) => {
var user = res.user
var username = req.query.user
var message = res.message
if (user != undefined){
res.render("publicprofile", {user:user, username:username, messages:message, usernamestr:String(username)})
} else{
res.redirect("/")
}
});
and the handlebars helper:
hbs.registerHelper('ifCond', function(v1, v2, options) {
if(v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});

Checkbox value is refreshed after page reload in node JS

"I am creating TODO list using Node as backend. after adding every new item, a checkbox is also generating in front of them so I can apply "CSS line-through" to let user know that item is done or of no use. But when I add another item, the page refreshes and that checkbox is unchecked as I am not storing that value anywhere. Can you tell me how to store the value of that checkbox in the backend?
HTML -
<div class="box" >
<% for (var i=0; i<newListItems.length; i++) { %>
<div class="item">
<input type="checkbox" id="checkBox">
<p> <%= newListItems[i] %> </p>
</div>
<% } %>
<form action="/" method="post" class="item">
<input class="inputBox" type="text" name="newItem" placeholder="New item" autocomplete="off" required="required">
<button type="submit" name="list" value=<%= listTitle%>> +</button>
</form>
</div>
Node JS -
const items = [];
app.post("/", function(req, res){
let item = req.body.newItem;
items.push(item);
res.redirect("/");
});
The answer involves a lot of code, so I will give you a set of steps that can help in your case.
You need to change your data scheme. Currently looks like you are just storing the string in an array of items. You need to change it to be array of objects. Each object should have the field task and done. So you could know which task is done or not.
app.post("/", function(req, res) {
let item = req.body.newItem;
items.push({ name: item, done: false });
res.redirect("/");
});
Next step will be adding an endpoint that will be changing the done field of an array item to true.
Then on a front-end you will need to write some JS code that will be sending an HTTP request to the endpoint that marks the task as done. You need to use AJAX call for that, for example, NPM package axios.
Change the template to reflect the changes to the data. e.g. instead of <%= newListItems[i] %> do <%= newListItems[i].name %> and add logic to render checked checkbox based on done property.
It worth to mention, that you should not store data in memory, because once the process is done, you will lose your data. It is okay for learning purposes, but in production, you should use a database.

Express: POST does not send data - var is not defined

In a view, i am trying to get the data that a user sent, via a form, from another view.
This is the view with the form (i have omitted some EJS stuff to avoid confusion):
<form action="/renderer" method="POST" id="sc-form">
<label for="model">Choose a model:</label>
<select name="model" id="model">
<% data.forEach(function(dat) { %>
<option value="<%= dat %>"> <%= dat %> </option>
<% }); %>
</select>
<input type="submit" value="Render the model!" />
</form>
As you can see, the user selects from a dropdown, and then data is POSTed on /renderer.
So, let's handle this POST request on routes.js:
app.post('/renderer', function(req, res) {
var myModel = req.body.model;
res.render('renderer.ejs', {data: myModel});
});
Pretty basic, we get the data that the form sent and we send it to renderer.ejs as parameters.
Finally, let's grab the data on /renderer.ejs (this is inside a <script> tag):
var modelName = <%- JSON.stringify(data) %>;
And i get this error:
data is not defined
But why is that? Data is the name of the variable that the router sent to the view, as parameter.
This is the third day that i am trying to make POST data appear on another view. If anyone could help i would really appreciate it.
I finally found this.
The form has to contain role="form", or else it wouldn't work.

Nested loop to pull JSON database elements

I am attempting to create a dynamic group within a select2 field while I pull my data from a JSON file. I'm using a nested loop to first loop through the states, then loop through the colleges in that state. The <optgroup> label should be the state and the <option> should be the college.
What you see below is my current code, representing what I've tried.
JSON file with database info:
var collegeData = [
{
'Ohio':
[
{name: 'Colllege of Wooster', value: 'cow'},
{name: 'Ohio State University', value: 'osu'}
],
'Arizona': [
{name: 'Arizona State University', value: 'asu'}
]
}
];
Select2 with ejs loops:
<select class="single-select" id="college" name="college">
<option value="default"></option>
<% for(var i = 0; i < college.length; i++) {%>
<optgroup label="<%=college[i] %>">
<% for(var j = 0; j < college[i][j].length; j++) {%>
<option value="<%=college[i][j].value %>">
<%=college[i][j].name %></option>
<%}%>
</optgroup>
<%}%>
</select>
Controller:
var mongodb = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/collegeApp';
app.get('/', function(rep, res){
mongodb.connect(url, (error, database) => {
const db = database.db('collegesApp');
if (error) return process.exit(1);
console.log('Connection is linked');
const collection = db.collection('colleges');
collection.find({}).toArray(function(err, results){
if (err) throw err;
res.render('index', { nav, college: results });
});
});
});
Ideal output in HTML:
<select class="single-select" id="college" name="college">
<option value="default"></option>
<optgroup label="Ohio">
<option value="cow"> College of Wooster</option>
<option value="osu"> Ohio State University</option>
</optgroup>
<optgroup label="Arizona">
<option value="asu"> Arizona State University</option>
</optgroup>
</select>
The error I receive is a Cannot read 'length' of undefined, so I know there is something wrong. My thought is that it is something to do with my syntax, but if you have other thoughts I would be happy to hear.
I've also already taken a look at W3Schools JSON Arrays article, as well as a codeburst article on JSON arrays. Neither was as specific as I needed.
Thank you!
Try the following:
1. Execute this query in your controller to exclude _id from the result.
collection.find({}, { _id: 0 }).toArray(function(err, results){
...
2.Try the following loop in your ejs file.
<select class="single-select" id="college" name="college">
<option value="default"></option>
<% college.forEach((coll) => { %>
<% Object.entries(coll).forEach(([key, value]) => { %>
<optgroup label="<%= key %>" >
<% Object.entries(value).forEach(([cKey, cValue]) => { %>
<option value="<%= cValue.value %>"> <%= cValue.name %> </option>
<% }); %>
</optgroup>
<% }); %>
<% }); %>
</select>
Hope it works.

Iterate through a MongoDB object's data

I will start off with how my mongoDB data looks like:
_id : 5c5b450918cb2b121648ff7a
name : "dannondarko"
email : "dangilmail#gmail.com"
password : "$2a$10$3z5m1e9Pcfid72Q2GchCjeTD55/SsIxmtWr3I1ZiA.DX/KlpfTbdK"
date : 2019-02-06 20:35:21.973
__v : 0
posts : Array
0 : Object
note : "test for the user dannondarko"
date : "02/08/2019"
This is just a side project and most likely will never be live so don't worry about the security of me posting this data! As for how I am procession the code in my server code:
app.get('/:username', (req, res) => {
username = req.params.username.toLowerCase();
const collection = req.app.locals.collection;
collection.find({ name: username }).toArray(function (err, results) {
if (err) {
res.status(500).send("Error communicating with the DB.");
} else if (results.length > 0) {
console.log("Here are the results: " + results);
console.log({people: results});
res.status(200).render('profile', {posts: results, name: username});
} else {
next();
}
});
});
What I am doing with this code is say you head to the address bar '/dannondarko', it should find 'dannondarko' in the collection, which it does fine, and then the 'results' variable is the complete object that I posted above. What I am trying to do is just get the 'posts' data, such as the note and date.
The note and date is the only data I need, which will be sent to this .ejs file that should create a post (kind of like FB) that shows the users' notes and date of the post. Here is my .ejs file:
<h1 class="mt-4"><%= name %></h1>
<div class="container">
<br>
<% for(var i=0; i < posts.length; i++) { %>
<div class="container">
<label><%= posts[i].note %></label>
<div class="container">
<label><%= posts[i].date %></label>
</div>
</div>
<% } %>
</div>
I hope that's enough information. I believe my downfall is not knowing how to just extract the 'posts' array from MongoDB from a certain user and iterate through the objects and sending over the note and date to the .ejs.
The results is an array of documents and you render this array to ejs as posts. Now in your ejs file posts represent the array of documents, not the posts array. So if you want to loop through all results you should edit your code like this:
<% posts.forEach(post => { %>
<h1 class="mt-4"><%= post.name %></h1>
<div class="container">
<br>
<% post.posts.forEach(p => { %>
<div class="container">
<label><%= p.note %></label>
<div class="container">
<label><%= p.date %></label>
</div>
</div>
<% }) %>
</div>
<% }) %>
If i understand well your mongo model structure the above should help you.

Resources