Displaying rest api response data in react - reactjs

Here response data contains{name ,details} fields. I have a upload button to upload single/multi files. After uploading files, I don't refresh the page. Now for ex, I upload single file and displayed the response. Again I upload 2 files. Now I should be able to display response of current upload as well as previous one. It should be in the following format:
1.Name1
Details1
2. Name2
Details2
3. Name3
Details 3
this.state.list = this.state.list.concat(details);
this.state.list_name = this.state.list_name.concat(name);
< form onSubmit={this.handleSubmit} >
<label>
Upload a file: <br /><br />
<input type="file" name="file" multiple onChange{this.onChangeHandler}/>
</label>
<br /><br />
<button type="submit">
Upload</button>
</form >
<ol>
// {this.state.list_name.map((k) =>
// <li>{k} :</li>)}
//{this.state.list.map((k) =>
// <li>{k}</li>
// )}
</ol>
handleSubmit = (event) => {
event.preventDefault();
const formData = new FormData();
for (var x = 0; x < this.state.selectedFile.length; x++) {
formData.append('inputFile', this.state.selectedFile[x])
fetch('url', {
method: 'POST',
body: formData
}).then(res => {
return res.json()
})
.then((res) => {
this.setState({
details: res.data.details,
name: res.data.name
})
console.log("res data", res)
//console.log("Data is", res.data.name) //displays name in the console
})
.catch(error => console.log('ERROR message'))
}
};
I have commented the code that I have tried. Thanks in advance.

you can do this
remove this
this.state.list = this.state.list.concat(details);
this.state.list_name = this.state.list_name.concat(name);
add this
fetch('url', {
method: 'POST',
body: formData
}).then(res => {
return res.json()
})
.then((res) => {
const list = this.state.list;
list.concat(res.data.details);
const list_name = this.state.list_name;
list_name.concat(name);
this.setState({
list,
list_name,
details: res.data.details,
name: res.data.name
})
console.log("res data", res)
//console.log("Data is", res.data.name) //displays name in the console
})
.catch(error => console.log('ERROR message'))
}

Related

Formik send undefined PostId and UserId to Backend

I have a component with a Formik form for creating a new comment.
On the back, the comment needs PostId, UserId and text.
When I try to post, my console.logs on front return all the data, but I get an "error 400, Comment.UserId and Comment.PostId cannot be null" and the back receives all data undefined.
How it's possible?
If this data was undefined, all console.log should return undefined too, right?
CommentForm:
function newComment(values) {
const formData = new FormData();
formData.append("firstName", firstName);
formData.append("lastName", lastName);
formData.append("UserId", UserId);
formData.append("PostId", PostId);
formData.append("text", values.text);
console.log("UserId", UserId);
console.log("firstName", firstName);
console.log("lastName", lastName);
console.log("PostId", PostId);
console.log("text", values.text);
console.log(props.id);
axios({
method: "post",
url: `http://localhost:8000/api/comments/${props.id}`,
data: formData,
headers: {
"Content-Type": "multipart/form-data",
Authorization: `Bearer ${AuthState.token}`,
},
})
.then((res) => {
if (res.status === 201) {
console.log("Success");
window.location.reload(true);
}
})
.catch(function (error) {
console.log(error)
});
}
<Formik
initialValues={{ text: "" }}
onSubmit={(values) => {
if (!values.text) {
setErrorMessage("Need text");
} else {
newComment(values);
}
}}
>
<Form>
<div>
<Field
name="text"
type="contentarea"
placeholder="Text Comment"
/>
<ErrorMessage name="text" className="errorInput" />
</div>
<Button
type="submit"
title="Post comment"
aria-label="Comment"
>
Comment
</Button>
</Form>
</Formik>
Comment controller:
exports.createComment = async (req, res, next) => {
const postObject = req.body;
const UserId = req.body.UserId;
const PostId = req.body.PostId;
const firstName = req.body.firstName;
const lastName = req.body.lastName;
if (!req.body) return res.status(403).send("Veillez saisir un texte");
console.log(req.body);
console.log(UserId);
console.log(PostId);
console.log(firstName);
console.log(lastName);
const comment = new Comment({
text: req.body.text,
UserId: UserId,
PostId: PostId,
firstName: firstName,
lastName: lastName,
});
comment
.save()
.then(() => res.status(201).json({ message: "Commentaire posté" }))
.catch((error) => res.status(400).json({ error }));
};
My Back is working (tested with Postman) and I used formik for other components inside the project and it works.
I don't understand why it can't send the data in this case.

React upload and display image

I don’t understand how to upload a photo correctly and then upload it to the page.
I'm a beginner, can you please tell me what I did wrong?
const [photo, setPhoto] = useState('');
const handleSubmit = (e) => {
e.preventDefault();
const users = {name, email, phone, position, photo}
setIsPending(true);
fetch("http://localhost:8000/users", {
method: 'POST',
headers: {'Content-Type':'application/json'},
body: JSON.stringify(users)
}).then(() => {
console.log('well');
setIsPending(false);
})
}
<form className="form" onSubmit={handleSubmit}>
<UploadFile
name="file"
onChange={(e) => setPhoto(e.target.files[0])}
value= {photo}
/>
<Button type="submit"/>
</form>
First of all you have to find a service that allows you to upload a file.
for example: https://api.imgur.com/endpoints/image/
there instructions inside.
However if you want to use fetch method I will give you an example how it should look like.
const handleSubmission = () => {
const formData = new FormData();
formData.append('File', selectedFile);
fetch(
'https://freeimage.host/api/1/upload?key=<YOUR_API_KEY>',
{
method: 'POST',
body: formData,
}
)
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
})
.catch((error) => {
console.error('Error:', error);
});
};
};
After recieving response from api service which is this part
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
})
.catch((error) => {
console.error('Error:', error);
});
You can set your state with the response url like this.
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
setPhoto(result.data.imageurl)
})
.catch((error) => {
console.error('Error:', error);
});
In the end you can use that image anywhere you want.
<img src={photo} />

Mulitple image add in react js

I am working on a project where I have one page where you should be able to add images. One by one it's worked perfectly. Now I want to make to be able to multiple add and upload. I don't want to use any library for image upload.
const onFileChange = (e) => {
const reader = new FileReader();
reader.onload = () => {
if (reader.readyState === 2) {
setPreview(reader.result);
}
};
reader.readAsDataURL(e.target.files[0]);
if (e.target.files[0]) {
setOver(true);
}
const copy = [...image];
copy.push(e.target.files[0]);
setImage([...copy]);
};
const onFileUpload = () => {
const formdata = new FormData();
image.forEach((elem) => {
formdata.append("data", elem);
});
formdata.append("id_grobnog_mjesta", Id);
addImage(formdata);
};
const addImage = async (data) => {
try {
setIsLoading(true);
const response = await apiRequest({
method: "post",
url: `spisak-srebrenica/upload`,
headers: {
Authorization: `Bearer ${token}`,
},
data,
});
if (response.data.success) {
getVictimImage();
}
setIsLoading(false);
setImage([]);
} catch (err) {
setIsLoading(false);
setImage([]);
}
};
Upload component :
<Upload>
<BiImageAdd size={50} opacity={0.5} />
<input type="file" onChange={onFileChange} />
<div className="items">
<p>Dodajte sliku</p>
<span className="format">PNG,JPG,GIF do 10MB</span>
</div>
</Upload>
add multiple attribute
<input type="file" id="files" name="files" multiple>
https://www.w3schools.com/tags/att_input_multiple.asp

Cannot save image with multer and react

I'm trying to send some string and an image to my db from a form in React component. Everything is saved, also the image name, but the file is not in the pubblic/images folder. My req.file is alway undefined and my data always an empty object
This is the Multer middleware
//Multer
const path = require("path");
const multer = require("multer");
const store = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "public/images");
},
filename: function (req, file, cb) {
cb(null, Date.now() + path.extname(file.originalname));
},
});
//Upload parameters
const upload = multer({
storage: store,
});
this is the post request of node
router.post("/", upload.single("image"), verify, async (req, res, next) => {
console.log(req.file);
const book = new Book({
title: req.body.title,
author: req.body.author,
image: req.body.image,
});
try {
const savedBook = await book.save();
res.send(savedBook);
} catch (error) {
res.send(error);
}
});
React
const token = useSelector((state) => state.token.token);
const data = new FormData();
//set Cover on change
const onChange = (e) => {
console.log(e.target);
data.append("image", e.target.files[0]);
console.log(data);
};
//Post Register
const Submit = async (e) => {
e.preventDefault();
await axios
.post(
"http://localhost:3000/api/book",
{
title: titleInput,
author: authorInput,
image: data,
},
{
headers: {
"auth-token": token,
},
}
)
.then((res) => {
console.log(res);
console.log(data);
})
.catch((error) => {
// handle error
console.log(error);
});
setAuthor("");
setTitle("");
};
Form
<form encType="multipart/form-data">
<input
type="text"
id="title"
value={titleInput}
name="title"
placeholder="title"
onChange={(e) => {
setTitle(e.target.value);
}}
/>
<input
type="text"
id="author"
value={authorInput}
name="author"
placeholder="Author"
onChange={(e) => {
setAuthor(e.target.value);
}}
/>
<input type="file" name="image" onChange={onChange} />
<button type="submit" onClick={Submit}>
Submit
</button>
</form>
Solved by changing the component code and sending data (create with Format()) to the node app.
//Post Register
const Submit = async (e) => {
e.preventDefault();
console.log(filename.name);
const data = new FormData();
data.append("author", authorInput);
data.append("title", titleInput);
data.append("image", filename);
data.append(
"imageTitle",
titleInput.split(" ").join("").toLowerCase() + ".jpg"
);
await axios
.post("http://localhost:3000/api/book", data, {
headers: {
"auth-token": token,
},
})
.then((res) => {
console.log(res);
})
.catch((error) => {
// handle error
console.log(error);
});
setAuthor("");
setTitle("");
};

How to clear the input after posting the data through fetch and making the code execute successful

I'm new to react, have created a chat using reactjs. I'm using "POST" request through fetch to post new message for a particular conversation. My Objective is when i send a message, then it should clear the input but unable to clear the input after sending message. Need to write for error also.. Anyone can help me in this?
myCode:
handleChange = event => {
this.setState({ [event.target.name]: event.target.value });
};
handleSend = event => {
const { phonNo } = this.props.phonNo;
event.preventDefault();
console.log("phone : " + "+" + phonNo);
this.setState({ toPhoneno: phonNo });
console.log("phonefkjdk : " + "+" + this.state.toPhoneno);
const data = {
toPhoneno: "+" + this.state.toPhoneno,
body: this.state.body
};
fetch("/api/messages", {
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" }
})
.then(res => res.json())
.then(() => {});
};
render () {
return (
<div>
<input
className="sendMessage"
onChange={this.handleChange}
/>
<Button onClick={this.handleSend} className="sendBtn" icon>
<Icon name="send" color="blue" />
</Button>
</div>
);
}
Can anyone help me in this ? Thanks in advance
You can clear it end of the fetch Promise chain.
fetch("/api/messages", {
method: "POST",
body: JSON.stringify(data),
headers: { "Content-Type": "application/json" }
})
.then(res => res.json())
.then(() => {
this.setState({ sendMessage: "" })
});
input should be controlled and it should have a name.
render () {
return (
<div>
<input
className="sendMessage"
name="sendMessage"
value={this.state.sendMessage}
onChange={this.handleChange}
/>
<Button onClick={this.handleSend} className="sendBtn" icon>
<Icon name="send" color="blue" />
</Button>
</div>
);
}

Resources