Reputation: 809
I want to make a request multiple data in one request with loop, but as far as I tried it always run Asynchronously (I guess?). I'm using Reactjs Redux and Express.
Here's my code :
profile.jsx
while(i < condition.length) { // say that length = 4
myData.forEach(item => addingData.push(item))
// Here I'm calling my request
this.props.addEmployee(addingData)
// I wanted to make this 'i' increase ONLY when the request is done.
// But I'm not sure how to do that
i++
}
Express Request
router.post("/add-employee", (req, res) => {
Employee.findOne({ _id: req.id }).then(user => {
if (user) {
const newEmp = new Employee({
nip: req.body.nip,
name: req.body.name
})
// add to employee model. Save employee
newEmp
.save()
.then(user => {
// Variable for profile
const newProfile = {}
newProfile.user = user._id
// Save profile
new Profile(newProfile).save()
console.log("selesai save")
res.status(200).json(user)
} else {
// error
}
})
})
this always returns the last data with 4 copies, which means it adding four data and its all same. How do I accomplish this, I read that this is because the request didn't run synchronously but how can I do that?
Thank you for your help!
UPDATE
as suggested by @Nathan Fries, I created a new router to handle the multiple requests with an array of object. But I still got the Synchronous problem (I guess?). Here's my code :
profile.jsx
for (i; i < this.state.file.length; i++) {
this.state.file[i].map(item => temp.push(item))
addData.push({
nip: temp[0],
name: temp[1]
})
temp = []
}
// make a request
this.props.addMultipleEmployee(addData)
routes/api/employees.js
// create/add multiple karyawan
router.post(
"/add-multiple-karyawan",
passport.authenticate("jwt", {
session: false
}),
(req, res) => {
let errors
let isValid
let newEmp
let i = 0
// console.log(req.body)
// this req.body value :
// [{nip: "nip1", name: "name1"},
// {nip: "nip2", name: "name2"}]
for (i; i < req.body.length; i++) {
isValid = validationEmployee(req.body[i]).isValid
errors = validationEmployee(req.body[i]).errors
if (!isValid) {
return res.status(404).json(errors)
}
console.log("checking for sure")
console.log(req.body[i])
// The value was still there
Nip.findOne({ nip: req.body[i].nip }).then(profile => {
if (profile) {
return res.status(400).json({
nip: "NIK tidak valid, karena ini adalah NIK admin. Coba lagi"
})
} else {
// But when it's trying to findOne, the error message said
// 'nip' are undefined
Karyawan.findOne({
nip: req.body[i].nip
}).then(exists => {
if (exists) {
return res.status(400).json({
nip: "Karyawan telah terdaftar dengan NIK yang sama."
})
} else {
// adding request.body to mongoDB
newEmp = new Karyawan({
nip: req.body[i].nip,
name: req.body[i].name
})
// add to employee model. Save employee
newEmp
.save()
.then(user => {
// Variable for profile
const newProfile = {}
newProfile.user = user._id
// Save profile
new Profile(newProfile).save()
console.log("selesai save")
res.status(201).json(user)
})
.catch(err => {
console.log(err)
})
}
})
}
})
}
}
)
and I got this error :
TypeError: Cannot read property 'nip' of undefined
[0] at D:\Kuliah\Semester-7\ptpnx-jombang\routes\api\employees.js:198:32
[0] at processTicksAndRejections (internal/process/task_queues.js:85:5)
[0] (node:22236) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
[0] at ServerResponse.setHeader (_http_outgoing.js:464:11)
[0] at ServerResponse.header (D:\Kuliah\Semester-7\ptpnx-jombang\node_modules\express\lib\response.js:771:10)
[0] at ServerResponse.send (D:\Kuliah\Semester-7\ptpnx-jombang\node_modules\express\lib\response.js:170:12)
[0] at ServerResponse.json (D:\Kuliah\Semester-7\ptpnx-jombang\node_modules\express\lib\response.js:267:15)
[0] at D:\Kuliah\Semester-7\ptpnx-jombang\routes\api\employees.js:247:22
[0] at processTicksAndRejections (internal/process/task_queues.js:85:5)
[0] (node:22236) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
[0] (node:22236) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process
with a non-zero exit code.
It is said that I need to make it Synchronously with Async/await or Promise? But I'm not sure how to do that. I still a novice with Async/await and Promise.
Thank you for your help!!
Upvotes: 2
Views: 429
Reputation: 1524
Why don't you add a /add-employees
route for handling of multiple employee additions? You could push them to an array in your jsx, then send them all at once. This avoids the async
issue entirely.
You are also declaring newEmp
with const
instead of let
. You can get the length by req.length
and iterate through the array.
Upvotes: 1