I am Selecting Multiple Files and using Multer saving Files to a specific folder. But if i am uploading Single file it is working Fine but if Selected More than two it is giving me an
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client. I am frustrated solving it. Can anyone one help me out yrr.
<div className="mb-3" >
<CFormLabel htmlFor="formFileMultiple">Select Resources</CFormLabel>
<CFormInput
multiple
onChange={(event) => formikProps.setFieldValue('fileName', event.target.files)}
accept="application/pdf, application/zip"
type="file" id="formFileMultiple" />
<p style={{ color: 'red' }}>{formikProps.touched.fileName && formikProps.errors.fileName}</p>
</div>
const handleAddResources = async ({ fileName }) => {
try {
const data = new FormData();
// data.append("fileName", fileName);
data.append("courseId", props.currentUser.item.course_id);
for (let i = 0; i < fileName.length; i++) {
// newArr.push(fileName[i]);
data.append("fileName", fileName[i]);
let response = await axios.post(`${ConfigData.SERVER_URL}/admin/resources/addResources`, data, {
})
if (response.data.status == false) {
throw Error(response.data.message)
}
else {
console.log("Success")
setthrowAlert(true);
}
}
} catch (error) { console.log(error) }
}
router.post('/addResources', fileUpload.array('fileName', 100), async (req, res) => {
try {
if (req.body && req.files) {
req.files.map(async(item) => {
console.log("ITEM--->", item);
let ResourcePost = new ResourcesPost({
originalname: item.originalname,
FileName:item.filename,
courseId: req.body.courseId,
mimetype:item.mimetype,
encoding:item.encoding,
size:item.size,
destination:item.destination
})
let uploadData = await ResourcePost.save()
if (uploadData) {
res.status(200).json({ status: true, data: uploadData })
} else {
res.status(500).json({ status: false, message: err.message })
}
})
} else {
console.log("Resourses Not Found !");
}
}
catch (error) {
console.log(error);
}
})
Related
I need to upload images from the front and that they reach the back to be able to show themselves but I have not been able to find the trick, if someone knows I would greatly appreciate it.
this is my error in the server
req files : undefined
ss ss
I'm using a react library for forms 'React-hook-form', it would be supposed that only with the field and the selected image it would be sent but when looking at the console I get undefined in the image field and in the others if it captures me the value
my front
const postCategories = async (data) => {
try {
setLoading(true);
const response = await instance.post("/categories", data);
console.log(response);
setLoading(false);
toast.success(response.data.msg);
getCategories();
setModalAdd(false);
} catch (err) {
console.log(err);
setLoading(false);
toast.error(err.response.data.msg);
}
};
console.log(data);
const bodyModalAdd = (
<Box sx={style}>
<h3 className="text-xl font-semibold">AƱadir categoria</h3>
<form onSubmit={handleSubmit(postCategories)}>
<div>
<label>imagen</label>
<input
type="file"
{...register("urlImage", { required: true, })}
/>
</div>
my back
export const registarCategoria = async (req, res) => {
console.log("Intentas pasar aunque sea");
const { nombre, descripcion } = req.body;
console.log("req files : " , req.files);
console.log(nombre, descripcion);
if (nombre !== undefined && descripcion !== undefined) {
const categoriaExiste = await Categoria.findOne({
where: {
nombre: nombre,
},
});
if (categoriaExiste) {
return res.status(400).json({
msg: "Ya esta registrada la categoria ya esta registrado",
success: false,
});
}
try {
let resultadoImg = undefined;
if(req.files?.image){
resultadoImg = await uploadImage(req.files.image.tempFilePath)
}
if(resultadoImg){
await Categoria.create({
nombre,
descripcion,
urlImage : resultadoImg?.secure_url,
});
return res
.status(201)
.json({ msg: "Categoria creada correctamente", success: true });
}else{
return res.status(400).json({ msg: "No se pudo crear la categoria, falta imagen", success: false });
}
} catch (err) {
console.error(err);
}
} else {
res.status(400).json({
success: false,
msg: "Faltan datos",
});
}
};
I have tried many things including adding the headers to the request. Still does not work. I have looked everywhere and came here as a last resort.
My main.js (routes)
app.post("/timeclock/punchout", async (req, res) => {
let time = moment().unix();
let employeeid = req.body.empid2;
let date = moment().format();
let comments = req.body.comments;
return res.send({ error: false, message: "complete punch" });
});
my liquid file using jQuery and axios
<script>
toast = siiimpleToast.setOptions({
container: 'body',
class: 'siiimpleToast',
position: 'top|right',
margin: 15,
delay: 2,
duration: 3000,
style: {},
})
$("#form").submit(function(event) {
event.preventDefault()
let empid1 = $("#empid").val()
let comments1 = $("#comments").val()
axios.post('/timeclock/punchin', {comments: comments1, empid: empid1}).then(response => {
if(response.data.error == false) {
$("#form").trigger('reset')
toast.success('Punch Successful!')
} else if(response.data.error == true) {
toast.alert(response.data.message)
$("#form").trigger('reset')
}
}, (error) => {
console.log(error)
})
})
$("#form").submit(function(event) {
event.preventDefault()
let empid1 = $("#empid").val()
let commentsout1 = $("#commentsout").val()
axios.post('/timeclock/punchout', {commentsout: commentsout1, empid: empid1}).then(response => {
if(response.data.error == false) {
$("#form").trigger('reset')
toast.success('Punch Successful!')
} else if(response.data.error == true) {
toast.alert(response.data.message)
$("#form").trigger('reset')
}
}, (error) => {
console.log(error)
})
})
any ideas? I read that it automatically detects the content type. But I cant seem to override it.
I am trying to send multiple files from react to express server and then to microservice. The problem is that my express server is getting crashed whenever I try to upload multiple files.
Here is my express.js side code:
router.post("/upload-files", upload.array("file[]"), async function (req, res) {
let check = new FormData();
// check = req.files;
const file = req.files;
// console.log("DATA------------------------>", file);
// check.append("file", file.buffer, file.originalname);
await axios.post(
constants.URL2 +":9095/upload-files", check,
{
headers: {
...check.getHeaders(),
},
})
.then((res) => {
return res;
})
.then((result) => {
res.send(result.data);
});
});
Here is my React.js side code:
update = () => {
if (this.isValidForm()) {
$(".loader").css({ display: "block" });
$(".overlay").css({ display: "block" });
// const obj = {
// fullName: this.state.fullName,
// };
var formData = new FormData();
const size = this.state.fileData;
for (let i = 0; i < size.length; i++) {
console.log(this.state.fileData[i]);
formData.append("file[]", this.state.fileData[i]);
}
// formData.append("files", this.state.fileData);
const updateRequest = {
method: "POST",
headers: {
// "Content-Type": "application/json",
Authorization:
},
// body: JSON.stringify(obj),
body: formData
};
fetch(URL.BASE_URL + "upload-file", updateRequest)
.then((res) => {
if (res.status == 401) {
this.props.GETLOGGEDINUSER(null);
this.props.history.push("/");
} else {
return res.json();
}
})
.then((res) => {
if (res.statusCode == 0) {
this.props.history.push({
pathname: "/newScreen",
state: { notification: "File uploaded Successfully" },
});
toast.success("File uploaded Successfully");
$(".loader").css({ display: "none" });
$(".overlay").css({ display: "none" });
} else {
toast.error(res.message);
$(".loader").css({ display: "none" });
$(".overlay").css({ display: "none" });
}
});
} else {
}
};
I tried many ways to solve this but none of them works.
I have two directories where vue, node exist. And I have the vue build file in the node folder.
I am currently processing requests from nodes in the vue. However, the event occurs but the data does not cross.
I have the following code, I sent form data via create, but the return data is empty. Also, in mongodb, title and content are require: true, so I get an error like the title.
Please help me.
node/routes/api
...
const Post = require('../db/post');
router.post('/new', (req, res) => {
const post = new Post({
title: req.body.title,
content: req.body.content
});
post.save((err) => {
if (err) {
console.error(err);
res.json({ result: 0 });
return;
}
res.json({ result: 1 });
});
});
...
vue/src/component/new
<template>
<div id="form-group">
name : <input v-model="post.title">
content : <input v-model="post.content">
<button v-on:click="new" >New</button>
</div>
</template>
<script>
export default {
data: function () {
return {
post: {}
}
},
methods: {
new: function (evt) {
this.$http.post('/api/post/new', {
post: this.post
})
.then((response) => {
if (response.data.result === 0) {
alert('Error')
}
if (response.data.result === 1) {
alert('Success')
this.$router.push('/')
}
})
.catch(function (error) {
alert('error')
})
}
}
}
</script>
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
You need to be authenticated to vote on a poll. When you vote on a poll, there are 2 issues:
You can vote an infinite number of times until you leave or reload the page
When you reload the page, you are finally prevented from voting but instead of having the option you voted on pre-selected, it's always the second option that is preselected.
WHAT SHOULD HAPPEN:
Sign up/ Login, then vote on a poll. The moment you click on an option, the poll voting choice you made is locked and you can't vote more on that poll.
HOW THE FLOW OF MY CURRENT CODE WORKS:
When a user clicks on an option, the counter is increased and the vote is then saved in an array that is pushed to the User object in the database.
When the component loads, the database data for votes for the currently logged in user is saved through the ngOninit() method inside the local votes variable which is then used to check on which poll the user already voted and what vote he made. The issue is that the choice is made is always choice2 when that is not actually the case.
I understand why you can vote many times until the page reloads, but I just don't know how to immediately lock the poll after the user voted, on the client and on the backend (prevent more votes from being registered if user already voted on poll).
As for why it is already the second choice that is pre-selected, I have no idea.
CODE:
HTML
<div class="formWidth">
<form (ngSubmit)="onSubmit(f)" #f="ngForm">
<div class="form-group">
<label class="inputTitle" for="title">Poll Title</label>
<input
type="text"
id="title"
class="form-control"
[ngModel]="poll?.title"
name="title"
required maxlenth="30">
<label class="inputTitle" for="choice1">Choice1</label>
<input
type="text"
id="choice1"
class="form-control"
[ngModel]="poll?.choice1"
name="choice1"
required maxlenth="20">
<label class="inputTitle" for="choice2">Choice2</label>
<input
type="text"
id="choice2"
class="form-control"
[ngModel]="poll?.choice2"
name="choice2"
required maxlenth="20">
</div>
<button type="button" class="btn btn-danger" (click)="onClear(f)">Clear</button>
<button class="btn btn-primary" type="submit">Save</button>
</form>
</div>
COMPONENT
export class PollComponent {
#Input() poll: Poll;
constructor(private pollService: PollService) {}
votes: any;
// Pie
public pieChartLabels:string[] = [];
public pieChartData:number[] = [];
public pieChartType:string = 'pie';
public pieChartOptions:any = {};
ngOnInit() {
var result1 = parseFloat(((this.poll.counter1/(this.poll.counter2+this.poll.counter1))*100).toFixed(2));
var result2 = parseFloat(((this.poll.counter2/(this.poll.counter2+this.poll.counter1))*100).toFixed(2));
this.pieChartData = [result1, result2];
this.pieChartLabels = [this.poll.choice1, this.poll.choice2];
this.pieChartType = 'pie';
this.pieChartOptions = {
tooltips: {
enabled: true,
mode: 'single',
callbacks: {
label: function(tooltipItem, data) {
var allData = data.datasets[tooltipItem.datasetIndex].data;
var tooltipLabel = data.labels[tooltipItem.index];
var tooltipData = allData[tooltipItem.index];
return tooltipLabel + ": " + tooltipData + "%";
}
}
}
}
this.pollService.voted(localStorage.getItem('userId')).subscribe(
data => {
var result = JSON.parse(data);
this.votes = result.votes;
},
err => { console.log("NGONINIT ERROR: "+ err) },
() => { }
);
}
onEdit() {
this.pollService.editPoll(this.poll);
}
onDelete() {
this.pollService.deletePoll(this.poll)
.subscribe(
result => console.log(result)
);
}
onChoice1() {
this.pollService.increaseCounter1(this.poll);
this.onVote1();
var result1 = parseFloat(((this.poll.counter1/(this.poll.counter2+this.poll.counter1))*100).toFixed(2));
var result2 = parseFloat(((this.poll.counter2/(this.poll.counter2+this.poll.counter1))*100).toFixed(2));
this.pieChartData = [result1, result2];
}
onChoice2() {
this.pollService.increaseCounter2(this.poll);
this.onVote2();
var result1 = parseFloat(((this.poll.counter1/(this.poll.counter2+this.poll.counter1))*100).toFixed(2));
var result2 = parseFloat(((this.poll.counter2/(this.poll.counter2+this.poll.counter1))*100).toFixed(2));
this.pieChartData = [result1, result2];
}
onVote1() {
this.pollService.voteOn(this.poll.pollID, localStorage.getItem('userId'), 1);
}
onVote2() {
this.pollService.voteOn(this.poll.pollID, localStorage.getItem('userId'), 2);
}
belongsToUser() {
return localStorage.getItem('userId') == this.poll.userId;
}
alreadyVotedFor(choice: number) {
var result = "";
if (this.votes) {
for (var i = 0; i < this.votes.length; i ++) {
if (this.votes[i].pollID == this.poll.pollID) {
result = "disabled";
if (this.votes[i].choice == choice) {
result = "selected";
}
}
}
}
return result;
}
// events
public chartClicked(e:any):void {
}
public chartHovered(e:any):void {
}
}
SERVICE
updatePoll(poll: Poll) {
const body = JSON.stringify(poll);
const token = localStorage.getItem('token')
? localStorage.getItem('token')
: '';
const headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'Bearer '+token
});
return this.http.patch('https://voting-app-10.herokuapp.com/poll/' + poll.pollID, body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => {
this.errorService.handleError(error.json());
return Observable.throw(error);
});
}
increaseCounter1(poll: Poll) {
poll.counter1++;
const body = JSON.stringify(poll);
const token = localStorage.getItem('token')
? localStorage.getItem('token')
: '';
const headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'Bearer '+token
});
this.http.patch('https://voting-app-10.herokuapp.com/poll/vote/' + poll.pollID, body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => {
this.errorService.handleError(error.json());
return Observable.throw(error);
})
.subscribe();
}
increaseCounter2(poll: Poll) {
poll.counter2++;
const body = JSON.stringify(poll);
const token = localStorage.getItem('token')
? localStorage.getItem('token')
: '';
const headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'Bearer '+token
});
return this.http.patch('https://voting-app-10.herokuapp.com/poll/vote/' + poll.pollID, body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => {
this.errorService.handleError(error.json());
return Observable.throw(error);
})
.subscribe();
}
voteOn(pollID: string, userID: string, choice: number) {
var user;
this.http.get('https://voting-app-10.herokuapp.com/user/'+userID)
.map(response => response.json())
.subscribe(
json => {
user = JSON.parse(json);
if (user.votes == undefined) {
user.votes = [{pollID, choice}];
} else {
user.votes.push({pollID, choice});
}
const body = user;
const token = localStorage.getItem('token')
? localStorage.getItem('token')
: '';
const headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'Bearer '+token
});
return this.http.patch('https://voting-app-10.herokuapp.com/user/', body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => {
this.errorService.handleError(error.json());
return Observable.throw(error);
})
.subscribe();
}
)
}
voted(userID: string) {
const headers = new Headers({'Content-Type': 'application/json'});
return this.http.get('https://voting-app-10.herokuapp.com/user/'+userID,{headers: headers})
.map(response => response.json())
.catch((error: Response) => {
this.errorService.handleError(error.json());
return Observable.throw(error);
});
}
ROUTE (BACKEND)
router.patch('/vote/:id', function (req, res, next) {
var decoded = jwt.decode(getToken(req));
Poll.findById(req.params.id, function (err, poll) {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
if (!poll) {
return res.status(500).json({
title: 'No Poll Found!',
error: {poll: 'Poll not found'}
});
}
poll.title = req.body.title;
poll.choice1 = req.body.choice1;
poll.choice2 = req.body.choice2;
poll.counter1 = req.body.counter1;
poll.counter2 = req.body.counter2;
poll.save(function (err, result) {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
poll: 'Updated poll',
obj: result
});
});
});
});
router.patch('/:id', function (req, res, next) {
var decoded = jwt.decode(getToken(req));
Poll.findById(req.params.id, function (err, poll) {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
if (!poll) {
return res.status(500).json({
title: 'No Poll Found!',
error: {poll: 'Poll not found'}
});
}
if (poll.user != decoded.user._id) {
return res.status(401).json({
title: 'Not Authenticated',
error: {poll: 'Users do not match'}
});
}
poll.title = req.body.title;
poll.choice1 = req.body.choice1;
poll.choice2 = req.body.choice2;
poll.counter1 = req.body.counter1;
poll.counter2 = req.body.counter2;
poll.save(function (err, result) {
if (err) {
return res.status(500).json({
title: 'An error occurred',
error: err
});
}
res.status(200).json({
poll: 'Updated poll',
obj: result
});
});
});
});
Okay, at first your radio buttons don't get disabled, because you don't update the votes-array in your poll.component.ts after saving a vote.
I'm not sure if it's a good solution or not:
In your poll.service.ts:
voteOn(pollID: string, userID: string, choice: number) {
var user;
return new Promise((resolve) => { //Create a new promise to wrap the Subscriptions
this.http.get('http://localhost:3000/user/' + userID)
.map(response => response.json())
.subscribe(
json => {
user = JSON.parse(json);
if (user.votes == undefined) {
...
.catch((error: Response) => {
this.errorService.handleError(error.json());
return Observable.throw(error);
}).subscribe(() => {
resolve(user.votes); // <- Resolve your promise
})
}
)
});
}
And in your poll.component.ts:
voteOn(...).then((votes) => {
this.votes = votes; // To update your votes array
this.updateVote();
})
And I don't recommend to call functions in bindings, because it happens that the functions are called very often "to detect changes", like in your components.
So I would change the code in following way:
In your poll.component.ts:
vote:any //Added to your poll component
updateVote() {
this.vote = this.votes.find((vote) => {
return vote.pollID === this.poll.pollID;
});
}
You need to call this method in your ngOnInit method:
this.pollService.voted(localStorage.getItem('userId')).subscribe(
data => {
var result = JSON.parse(data);
this.votes = result.votes;
this.updateVote(); // <- To select the vote of this poll
},
err => { console.log("NGONINIT ERROR: " + err) },
() => { }
);
And in your poll.component.html:
<fieldset [disabled]="vote">
{{ poll.counter1 }} votes <input type="radio" id="{{ poll.choice1 }}" name="my_radio" value="{{ poll.choice1 }}" (click)="onChoice1(form)" [checked]="vote?.choice == 1"> {{ poll.choice1 }}
<br>
{{ poll.counter2 }} votes <input type="radio" id="{{ poll.choice2 }}" name="my_radio" value="{{ poll.choice2 }}" (click)="onChoice2(form)" [checked]="vote?.choice == 2"> {{ poll.choice2 }}
</fieldset>
But if you don't want to change your code in such a way, please tell me, so i can provide another solution.