问题
I have dynamically generated text boxes and each value has to be stored in a JSON array when posted. I pushed all the values to an array and when I post it, those values in an array are read as one object in a JSON array in my JavaScript server file.
For a better understanding, here's my code snippet below:
// my javascript server
const express = require("express");
const MongoClient = require("mongodb").MongoClient;
const app = express();
const {DB_URL} = require("./credentials");
const connectionString = DB_URL
MongoClient.connect(connectionString, {useUnifiedTopology: true})
.then(client => {
console.log('Connected to Database');
const db = client.db('todo-items');
const itemsCollection = db.collection('items');
app.use(express.urlencoded({extended: true}));
app.use(express.static("public"));
app.set("view engine", "ejs");
app.use(express.json());
var items = [];
app.get('/', (req, res) => {
db.collection('items').find().toArray()
.then(items => {
res.render('result.ejs', { items: items })
})
.catch(error => console.error(error))
})
app.get('/myForm', (req, res) => res.render("pages/myForm"));
app.get('/result', (req, res) => res.render("pages/result", {
items:items}));
app.post('/myForm', (req, res) => {
itemsCollection.insertOne(req.body);
items.push(req.body);
console.log(req.body);
res.redirect("/result");
});
app.put('/items', (req, res) => {
itemsCollection.findOneAndUpdate(
{ item: 'anything' },
{
$set:{
items: req.body.items
}
},
{
upsert: true
}
)
.then(result => res.json('Success'))
.catch(error => console.error(error))
})
app.delete('/items', (req, res) => {
itemsCollection.deleteOne(
{ items: req.body.items }
)
.then(result => {
if(result.deletedCount === 0) {
return res.json('Nothing to delete')
}
res.json('deleted the selected item')
})
.catch(error => console.error(error))
})
const port = 3000
app.listen(port, function () {
console.log(`listening on ${port}`)
})
}).catch(console.error)
<!-- this is my result.ejs -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/style.css">
<title>Assignment 2</title>
</head>
<body>
<p style="text-align: center; display: inline-block; color: black;">Enter the todo item you want to modify, and the new name you want to give it.</p></br>
<input type="text" id="item-given" cols="18" rows="2"></br>
<input type="text" id="item-update-or-delete" cols="18" rows="2"></br>
<button type="button" id="update-button">Update</button></br>
<button type="button" id="delete-button">Delete</button></br>
<div id="message"></div></br>
<form action="/todoitems" action="POST">
<fieldset class="items todo-list">
<legend class="todo-list__title">My Special Todo List</legend>
<% for(var i = 0; i < items.length; i++) {%>
<label class="item todo-list__label">
<input type="checkbox"/>
<i class="check"></i>
<span><%= items[i].items %></span>
</label>
<% } %>
</fieldset>
</form>
</body>
</html>
<!-- this is my myForm.ejs -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="https://code.jquery.com/jquery-3.5.0.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="myFormStyle.css">
<title>My Form</title>
</head>
<body>
<div class="container">
<br/>
<br/>
<div class="form-group">
<form method="post">
<div class="table table-bordered" id="item_field">
<h1>Todo Item 1</h1>
<input type="text" id="item1" class="task" cols="22" rows="2">
<button type="button" id="add" class="addButton">+</button></td>
</div>
<input type="submit" id="submit" value="Submit"/>
</form>
</div>
</div>
</body>
</html>
<script>
$(document).ready(function() {
var count = 1;
//var $itemIds = Array.from($('h1 + .task'));
//var ids = $itemIds.map(task => $(task).attr('id'));
$('#add').on('click', function() {
count++;
$('#item_field').append('</br><h1>Todo Item ' + count +'</h1><input type="text" id="item'+ count +'" class="task" cols="22" rows="2">');
$('#add').insertAfter('#item' + count);
});
$('#submit').on('click', function() {
var items = [];
for (let i = 1; i <= count; i++) {
items.push($('#item' + i).val());
}
$.ajax({
method: 'POST',
url:'/myForm',
type: 'POST',
data: {
items: items
}
}).
done(function(data) {
console.log(data);
}).
fail(function(error) {
console.log(error);
})
})
});
</script>
回答1:
If you want to insert the items individually, iterate over the array of items and insert each one, and redirect after they have finished inserting:
app.post('/myForm', (req, res) => {
const itemPromises = req.body.items.map(item => {
items.push(item);
return itemsCollection.insertOne(item); // returns a promise
});
Promise.all(itemPromises)
.then(() => res.redirect('/result')
.catch(console.error);
});
Also, you will have to change your $.ajax
call so that the data is being sent in the format you expect:
$.ajax({
method: 'POST',
contentType: 'application/json',
url:'/myForm',
data: JSON.stringify({
items: items
})
})
Finally, change your form element's attributes so that the form itself does not try to submit and only the ajax call is made:
<form method="post" action="javascript:void(0)">
<div class="table table-bordered" id="item_field">
<h1>Todo Item 1</h1>
<input type="text" id="item1" class="task" cols="22" rows="2">
<button type="button" id="add" class="addButton">+</button></td>
</div>
<input type="submit" id="submit" value="Submit"/>
</form>
Also, as you noted, this line <span><%= items[i].items %></span>
should instead be <span><%= items[i] %></span>
来源:https://stackoverflow.com/questions/61785639/how-to-send-each-string-object-in-an-array-as-ajax-post-data