How to upload image from input type with axios to mongodb? - image

I failed to save image in input fontend to mongdb, please help me to fix it. I tried to learn without being very good at it.
There might be some code error, please fix it for me.
My code
form
return (
<div className="form-group">
<label>อัพโหลดรูปภาพ</label>
<div className="input-group mb-3">
<input type="file"
className="form-control"
id="img"
accept="image/*"
name="img"
onChange={submitImg}
/>
</div>
<input type="submit" value="ส่งข้อมูล" className="btn btn-primary" />
)
}
export default FormComponent;
mongoose
const mongoose = require("mongoose")
const blogSchema = mongoose.Schema({
title:{
type:String,
required:true
},
content:{
type:{},
required:true
},
author:{
type:String,
default:"Admin"
},
img:{
data:Buffer,
contentType:String
},
slug:{
type:String,
unique:true
}
},{timestamps:true})
module.exports = mongoose.model("Blogs",blogSchema)
router
router.post('/create',upload.single('img'),create)
Save
exports.create = async (req, res) => {
let slug = uuidv4();
let saveBlog = new Blogs({
title: req.body.title,
content: req.body.content,
author: req.body.author,
img: {
data: fs.readFileSync("uploads/"+req.file.filename),
contentType: 'image/png' || 'image/jpg'
},
slug: slug
})
saveBlog
.save()
.then(() => {
console.log("Saved successfully!");
res.status(200).json({ 'blog': 'blog saved successfully' });
})
.catch(err => {
console.log("blog save unsuccessful!");
res.status(400).send('adding new blog failed');
});
}
Image does not save
I want to save multiple data Both the text and pictures

Related

Laravel and Vuejs 3 Image updating not working

I managed to create a post with image and now I want to be able to update it too. Everything was working fine with the update method when i upload new image and try to update i got old image new iamge isn't updating. Bellow my code:
<form #submit.prevent="UpdateService" enctype="multipart/form-data">
<div class="mb-4">
<label class="form-label" for="image">Upload Image</label>
<input type="file" name="image" #change="onChangeServiceUpdateImage" class="form-control"/>
<img :src="ServiceUpdateForm.url" class="img-fluid mt-2" width="100" />
<HasError :form="ServiceUpdateForm" field="image" />
</div>
</form>
VueComponenet.vue
export default {
data: () => ({
ServiceUpdateForm: new Form({
name: "",
status: "",
desc: "",
icon_class: "",
image: "",
url: "",
_method: "put",
}),
editor: ClassicEditor,
editorConfig: {},
language: 'en',
}),
methods: {
onChangeServiceUpdateImage(e){
// console.log(e.target.files[0]);
const file = e.target.files[0];
this.ServiceUpdateForm.url = URL.createObjectURL(file);
this.ServiceUpdateForm.image = file;
},
async UpdateService() {
let slug = this.$route.params.slug;
$api.post(`/service/${slug}`, this.ServiceUpdateForm).then(() => {
this.$router.push({ name: "backend-service-manage" });
Toast.fire({
icon: 'success',
title: 'Data Update Successful!'
})
}).catch(error => {
Toast.fire({
icon: 'error',
title: 'Data is missing!'
})
});
},
}
Controller
if($request->hasFile('image')){
// Delete Existing Image
if( File::exists('frontend/assets/img/service/' . $service->image) ) {
File::delete('frontend/assets/img/service/' . $service->image);
}
$logo = time().'.'.request()->file('image')->getClientOriginalExtension();
$request->selectedfile->move(public_path('frontend/assets/img/service'), $logo);
$service->image = $logo;
}
$service->save();
return response()->json('success', 200);

Axios post request error when sending an array with an image

I have a form that has an array input and an image, when sending the request without the image it's getting stored correctly in the database, when the image input and the "Content-Type": "multipart/form-data" header both added, it send the request with the correct data but it outputs that the array data is invalid.
the code is written in Vue 3 and the backend is a laravel api.
<script>
import axios from "axios";
export default {
name: "AddPayloadModel",
data() {
return {
drone_id: [],
drone_models: [],
image: null,
previewImage: null,
};
},
created() {
this.getDroneModels();
},
methods: {
getDroneModels() {
axios.get("http://127.0.0.1:8000/api/drone-models").then((response) => {
this.drone_models = response.data;
});
},
imgUpload(e) {
this.image = e.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(this.image);
reader.onload = (e) => {
this.previewImage = e.target.result;
};
},
submit(e) {
const form = new FormData(e.target);
const inputs = Object.fromEntries(form.entries());
inputs.drone_id = Object.values(this.drone_id);
console.log(inputs.drone_id);
axios
.post("http://127.0.0.1:8000/api/payload-model/add", inputs, {
headers: {
"Content-Type": "multipart/form-data",
},
})
.then((res) => {
if (res.data.isUnattachableDrones) {
console.log(res);
alert(res.data.unattachableDrones);
} else {
this.$router.push("/home");
}
})
.catch((e) => {
console.error(e);
});
},
},
};
</script>
<template>
<main class="form-signin">
<form #submit.prevent="submit">
<h1 class="h3 mb-3 fw-normal">Add Payload Model</h1>
<div class="form-floating">
<input
class="form-control"
autocomplete="off"
name="brand_name"
placeholder="Brand Name"
/>
<label>Brand Name</label>
</div>
<div class="form-floating">
<input
class="form-control"
autocomplete="off"
name="model_name"
placeholder="Model name"
/>
<label>Model Name</label>
</div>
<div class="form-floating">
<input
class="form-control"
autocomplete="off"
name="type"
placeholder="Type"
/>
<label>Type</label>
</div>
<select
v-model="drone_id"
multiple="multiple"
name="drone_id"
style="height: auto"
class="form-select last-input"
>
<template v-for="drone in drone_models">
<option :value="drone.id">
{{ drone.brand_name }}
</option>
</template>
</select>
<input
name="image"
ref="fileInput"
accept="image/*"
type="file"
#input="imgUpload"
/>
<button class="w-100 btn btn-lg btn-form" type="submit">Submit</button>
</form>
</main>
</template>
here is the response when submitting the form.
and here is the payload.
It got solved by changing the way to push data to the post request to a formData and append it manually like this.
submit() {
const formData = new FormData();
formData.append(
"brand_name",
document.getElementById("brand_name").value
);
formData.append(
"model_name",
document.getElementById("model_name").value
);
formData.append("type", document.getElementById("type").value);
formData.append("image", document.getElementById("image").files[0]);
this.drone_id.forEach((drone_id) => {
formData.append("drone_id[]", drone_id);
});
const headers = { "Content-Type": "multipart/form-data" };
axios
.post("http://127.0.0.1:8000/api/payload-model/add", formData, headers)
.then((res) => {
console.log(res);
if (res.data.isUnattachableDrones) {
console.log(res);
alert(res.data.unattachableDrones);
} else {
this.$router.push("/home");
}
})
.catch((e) => {
console.error(e);
});
},

How to Upload pdf, xls, xlsx, doc, docx in Laravel and Vue.js

My Code is below but it's not working. I can upload Image with base64 formate and successfully store on Laravel backend but I'm struggling to upload other file formates in Laravel and vue.js. Anyone can help please?
.vue file
<template>
<div>
<form enctype="multipart/form-data" #submit.prevent="handleSubmit">
<div class="form-group mb-4">
<label>Institute Prospectus</label>
<label class="custom-file-container__custom-file">
<input
type="file"
class="form-control-file"
#change="onChangeProspectus"
/>
</label>
</div>
</form>
</div>
</template>
<script>
export default {
data() {
return {
institute_prospectus: "",
};
},
methods: {
handleSubmit() {
let data = {
institute_prospectus: this.institute_prospectus,
};
axios.post(data, "/add-institute")
.then(() => {
console.log("Success");
})
.catch((err) => {
console.log(err);
});
},
onChangeProspectus(event) {
let file = event.target.files[0];
this.institute_prospectus = file.name;
},
},
};
</script>
InstituteController.php
public function add_institute(Request $request) {
$prospectus_file = $request->institute_prospectus;
if ($prospectus_file) {
$ext = substr($prospectus_file, strrpos($prospectus_file, '.', -1), strlen($prospectus_file));
$name = time().'-'.$slug.".".$ext;
$upload_path = 'backend/files/institute/';
$prospectus_url = $upload_path.$name;
$prospectus_file->move($upload_path,$prospectus_url);
}
}

Return submitted POST data with Alpine.js and new FormData()

I'm attempting to POST some form data, using Alpine.js, to the current page which would then be used by PHP $_GET to run some functionality.
It seems to be returning the entire page in the response, rather than the form data (which then errors out due to it being invalid JSON).
How can I only return the submitted form data in the response?
<form
method="post"
action="./"
class="form__press"
x-on:submit.prevent="
let formData = new FormData();
formData.append('username', 'Chris');
fetch('./', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then((response) => response.json())
.then((result) => {
console.log('Success:', result);
})
.catch((error) => {
console.error('Error:', error);
});"
>
<div class="field mb:15#xs">
<label for="pressEmail">Email</label>
<input type="email" name="pressEmail" autocomplete="off" required />
</div>
<div class="field mb:15#xs">
<label for="pressPassword">Password</label>
<input type="password" name="pressPassword" autocomplete="new-password" required />
</div>
<button type="submit" name="submit">Submit</button>
</form>
So the right answer to this is that you need your PHP backend function to return JSON with the correct content-type ("application/json").
However you can also achieve this client side since you've got all the data you want returned.
<form
method="post"
action="./"
class="form__press"
x-on:submit.prevent="
let formData = new FormData();
formData.append('username', 'Chris');
fetch('./', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
})
.then(() => JSON.parse(JSON.stringify(formData)))
.then((result) => {
console.log('Success:', result);
})
.catch((error) => {
console.error('Error:', error);
});"
>

Unable to upload a file using Vue.js to Lumen backend?

I have tried to upload a file using vue.js as front end technology and laravel in the back end. I have tried to pass the file object using formData javascript object but the server responds as the value is not passed.
I have tried to log the file using console.log and it appropriately displays the data.
Consider that I have discarded some field names.
Template Code
<template>
<b-container>
<div align="center">
<b-card class="mt-4 mb-4 col-md-8" align="left" style="padding: 0 0;">
<card-header slot="header" />
<b-form>
<div class="row">
<div class="col-6 col-md-6">
<b-button
type="submit"
variant="success"
class="float-right col-md-5"
v-if="!update"
#click="save"
squared
>
<i class="fas fa-save"></i>
Save
</b-button>
</div>
</div>
<hr style="margin-top: 10px;" />
<b-form-group
label-cols="12"
label-cols-lg="3"
label-for="input-2"
label="Remark: "
label-align-sm="right"
label-align="left"
>
<b-form-textarea
id="textarea"
v-model="record.remark"
rows="2"
max-rows="3"
></b-form-textarea>
</b-form-group>
<b-form-group
label-cols="12"
label-cols-lg="3"
label-for="input-2"
label="Remark: "
label-align-sm="right"
label-align="left"
>
<b-form-file
v-model="record.attachement"
:state="Boolean(record.attachement)"
placeholder="Choose a file..."
drop-placeholder="Drop file here..."
></b-form-file>
</b-form-group>
</b-form>
<status-message ref="alert" />
</b-card>
</div>
</b-container>
</template>
Script Code
<script>
import { mapGetters, mapActions } from "vuex";
export default {
props: ["id", "user_id"],
data: () => ({
record: {
remark: "",
attachement: null
}
}),
methods: {
...mapActions([
"addBenefitRequest",
]),
save(evt) {
evt.preventDefault();
this.$validator.validate().then(valid => {
if (valid) {
const Attachement = new FormData();
Attachement.append("file", this.record.attachement);
var object = {
remark: this.remark
};
this.addBenefitRequest(object, Attachement);
}
});
},
},
computed: mapGetters([
"getStatusMessage",
"getBenefitRequest",
])
};
</script>
Store Code
async addBenefitRequest({ commit }, object, Attachement) {
try {
const response = await axios.post(
commonAPI.BENEFIT_BASE_URL + "/benefit-requests",
object,
Attachement,
{
headers: {
"Content-Type": "multipart/form-data"
}
}
);
commit("pushBenefitRequest", response.data);
commit("setStatusMessage", "Record has been added.");
} catch (error) {
return error
},
Controller Code
public function store(Request $request, Request $request2)
{
$this->validate($request, [
'employee_id' => 'required|string',
'requested_date' => 'required|date',
// 'benefit_type_id' => 'required|string|exists:benefit_types,id',
'reason' => 'required|string',
]);
$this->validate($request2, [
'attachement' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048'
]);
// $success = BenefitRequest::exists($request->employee_id);
// if(!$success)
// return response()->json("Employee doesn't exist", 422);
$id = (string) Str::uuid();
if($request2->attachement)
{
$attachement = $request2->file('attachement')->store('Benefits');
$request->merge(['attachement' => $attachement]);
}
// $request->attachement = $request->file('attachement')->store('Benefits');
$request->merge(['id' => $id]);
BenefitRequest::create($request->all());
return response()->json('Saved', 201);
}
Route
$router->post('',
['uses' => 'BenefitRequestController#store',
'group'=>'Benefit requests',
'parameter'=>'employee_id, requested_date, requested_by, benefit_type_id, reason, remark, status',
'response'=>'<statusCode, statusMessage>'
]);
Here is an example. you can try it
index.vue
`<div id="app">
<div v-if="!image">
<h2>Select an image</h2>
<input type="file" #change="onFileChange">
</div>
<div v-else>
<img :src="image" />
<button #click="removeImage">Remove image</button>
</div>
</div>`
new Vue({
el: '#app',
data: {
image: ''
},
methods: {
onFileChange(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.createImage(files[0]);
},
createImage(file) {
var image = new Image();
var reader = new FileReader();
var vm = this;
reader.onload = (e) => {
vm.image = e.target.result;
};
reader.readAsDataURL(file);
},
removeImage: function (e) {
this.image = '';
}
}
})

Resources