Image uploading in Angular - javascript

I was trying to upload an image using Angular to a google storage bucket. And everything is working fine with Postman.
But I'm stuck with angular typescript. Can anyone suggest to me a way to do this?
.html file
<input type="file" accept="image/png, image/jpeg" class="form-control upload-btn" formControlName="imageUpload" placeholder="Upload Images" (change)="uploadImage($event)" required>
.ts file
uploadImage(event: any) {
if (event.target.files && event.target.files[0]) {
const uploadImage=event.target.files[0];
const fileObject = {
userId: this.userId,
bucketName: 'Test123',
image: uploadImage
};
this.userService.uploadImage(fileObject).subscribe(data=>{
},err=>{
console.log("error occured")
}
)
}
}
.service file
uploadImage(fileObject: any){
return this.http.post('http://localhost:1337' + 'upload-image' , fileObject);
}
No any error occurs on the backend side. It worked fine with Postman.
Im not sure about the .ts file.

As suggested by #PrasenjeetSymon using FormData will help to upload images in Angular.
Here is the similar thread which demonstrate how to use FormData
You can use the tag from HTML:
<input type="file" name="file" id="file" (change)="onFileChanged($event)" />
and in the component:
public files: any[];
contructor() { this.files = []; }
onFileChanged(event: any) {
this.files = event.target.files;
}
onUpload() {
const formData = new FormData();
for (const file of this.files) {
formData.append(name, file, file.name);
}
this.http.post('url', formData).subscribe(x => ....);
}

Related

how can i upload multiple files to s3 using nuxtjs

please I'm lost how can I upload multiple files
This is how I upload single files:
<div class="a-row a-spacing-top-medium">
<label class="choosefile-button">
<i class="fal fa-plus"></i>
<input
type="file"
#change="onFileSelected"
ref="files"
/>
<p style="margin-top: -70px">{{ fileName }}</p>
</label>
</div>
this is my script tag for image upload:
<script>
import axios from 'axios'
export default {
data() {
return {
selectedFile: null,
fileName: '',
photos: null
}
},
methods: {
onFileSelected(event) {
this.selectedFile = event.target.files[0]
console.log(this.selectedFile)
this.fileName = event.target.files[0].name
},
async onAddProduct() {
let data = new FormData()
data.append('photos', this.selectedFile, this.selectedFile.name)
const response = await axios
.post('http://localhost:5000/api/products', data)
.then(() => {
console.log(response)
})
}
}
}
</script>
each time I add multiple to my input tag it just uploads an image in my browser.
Please how can I go about multiple uploads?
Here's a basic blog post on how to upload a files to S3 in Vue through a node backend. This may help you out.
Basically what you need to do is create a backend that handles the files and uploads them. This can be done using multer, multer-s3 and node.
One thing that you should also change is just having
data.append('photos', this.selectedFile)
data.append('fileName', this.selectedFile.name)

filepond post image with metadata

i'm writing a upload page using filepond. The problem i'm facing is to get it to work like i want. I need to get the metadata from the input and post it with additional formdata
I can allready post the image and additional formdata. However I also want the metadata from the input. If I use onaddfile and log the metadata it works and shows additional="1"
<input type="file" id="img" name="img" data-file-metadata-additional="1">
pond=FilePond.create(document.querySelector('#img'),{
server: {
process: {
url: 'opbouw/model/post/addimg.php',
ondata: (formData) => {
// > POST META DATA
formData.append('userid', '2');
formData.append('usercom', '1');
return formData;
}
}
},
});
pond.onaddfile = (err, item) => {
console.log(item);
const metadata = item.getMetadata();
console.log(metadata);
}
So no clue how to post the metadata
If you're not going to write a custom server.process method then you're going to have to "remember" which metadata belongs to which file.
Something like this:
<input type="file" id="img" name="img" data-file-metadata-additional="1">
<script>
let pondMetadata;
const pond = FilePond.create(document.querySelector('#img'), {
server: {
process: {
url: 'opbouw/model/post/addimg.php',
ondata: (formData) => {
// add metadata
formData.append('usermeta', JSON.stringify(pondMetadata));
formData.append('userid', '2');
formData.append('usercom', '1');
return formData;
}
}
},
onaddfile: (err, item) => {
pondMetadata = item.getMetadata();
}
});
</script>

How to add multiple images to Firebase realtime database using Vuejs?

I am trying to upload images to realtime firebase database. I made it with one images but I have no idea how to add multiple images.
This is my solution for one image.
<v-layout row>
<v-flex xs12 sm6 offset-sm3>
<!-- accept nam govori da uzme slike i nista vise-->
<v-btn raised #click="onPickFile">Upload image</v-btn>
<input
type="file"
style="display:none"
ref="fileInput"
accept="image/*"
#change="onFilePicked"/></v-flex
></v-layout>
In data I have this two: imgURL: "",
image: null
And this is a method:
onFilePicked(event) {
//files is list of imaages by puting files[0] we are taking just one
const files = event.target.files;
let filename = files[0].name;
if (filename.lastIndexOf(".") <= 0) {
return alert("Please add a valid file!");
}
const fileReader = new FileReader();
fileReader.addEventListener("load", () => {
this.imgURL = fileReader.result;
});
fileReader.readAsDataURL(files[0]);
this.image = files[0];
},
Although, this is not a firebase related question, but I try to help anyway:
First of all, you should add multiple to the input-tag, so you can select more than only one file there:
// CHANGE THIS:
<input type="file" style="display:none" ref="fileInput" accept="image/*" #change="onFilePicked"/>
// TO THIS:
<input type="file" style="display:none" ref="fileInput" accept="image/*" #change="onFilePicked" multiple/>
I assume you stumbled upon this wierd 'for-loop' for the files.. I had the same issue and figured out when I type of instead of in, then I get the file itself, not just the index and there is no error.
I splitted up the main parts of your function and converted them in asyncron Promises (because there might be a timing error with the addEventListener)
This is just the idea of the multiple files upload. Maybe you should add some more error-catcher:
new Vue({
data: {
blobs: [],
images: [],
},
methods: {
async onFilePicked(event) {
const files = event.target.files
this.images =[]
this.blobs =[]
for (let file of files) {
this.images.push(file)
let blob = await this.prepareImagesForUpload(file)
this.blobs.push(blob)
}
this.uploadImagesToFirebase()
},
prepareImagesForUpload(file) {
return new Promise((resolve, reject) => {
let filename = file.name
if (filename.lastIndexOf(".") <= 0) {
alert("Please add a valid file: ", filename)
reject()
}
const fileReader = new FileReader()
fileReader.readAsDataURL(file)
fileReader.addEventListener("load", async () => {resolve(fileReader.result)})
})
},
uploadImagesToFirebase() {
//... do the firebase upload magic with:
console.log(this.blobs)
//...
}
}
})

send data with json format in angular 8 with formData

i need to send data from server by this format :
{
"name":"kianoush",
"userName":"kia9372",
"email":"kiadr9372#gmail.com"
}
i try to do this work :
update(item:UserEditModel): Observable<any>{
const formData: FormData = new FormData();
for (const key in item) {
if (item.hasOwnProperty(key)) {
if (item[key] instanceof File) {
formData.append(key, item[key], item[key].name);
} else {
formData.append(key, item[key]);
}
}
}
return this.httpClient.post(this.appConfig.apiEndpoint+'User/UpdateUser',
formData, {
headers:this.headers,
reportProgress: true,
observe: 'events'
})
.pipe(map(response => response || {} as HttpEvent<any>));
}
but it send to server by this format :
------WebKitFormBoundaryhWmbFWpD25WdeB9n
Content-Disposition: form-data; name="firstName"
vbnvbnvb
------WebKitFormBoundaryhWmbFWpD25WdeB9n
Content-Disposition: form-data; name="lastName"
vbnvbnvn
------WebKitFormBoundaryhWmbFWpD25WdeB9n
Content-Disposition: form-data; name="userName"
vbnvbnvb
------WebKitFormBoundaryhWmbFWpD25WdeB9n
Content-Disposition: form-data; name="roleId"
but i want to send data from server by this format :
{
"name":"kianoush",
"userName":"kia9372",
"email":"kiadr9372#gmail.com"
}
now how can i solve this problem ???
because you have the formdata its format is deferent from JSON
And if you don't have a file in the request just convert the formdata
to JSON
Or in the backend use [FromForm] before the dto
Normally when I have some files that should go to the server
I am using this kind of solution you can do it like this
First:
slectedFile: File;
//imgUrl for showing it in the html tag
imgUrl = '../assets/img/profilepic.png';
Second:
form: FormGroup = this.fb.group({
//........
file: [null]
});
Third:
onFileSelect(file) {
if (file.target.files[0]) {
this.slectedFile = file.target.files[0] as File;
const reader = new FileReader();
reader.readAsDataURL(this.slectedFile);
reader.onload = (event: any) => {
this.imgUrl = event.target.result;
};
}
}
And Last:
which I assume your main problem is here
const data= new FormData();
if (this.slectedFile) {
data.append('file', this.slectedFile, this.slectedFile.name);
}
and I should mention that personally use this package for input
https://www.npmjs.com/package/ngx-material-file-input
and in the html side you just say :
<mat-form-field class="col-md-12 ml-10 ngxmatfileinput">
<ngx-mat-file-input
(change)="onFileSelect($event)"
formControlName="file"
accept="image/*">
</ngx-mat-file-input>
<img [src]="imgUrl" class="float-left icon-fileupload" />
</mat-form-field>
if you not send file use following code
update(item:UserEditModel): Observable<any>{
const _data ={
"name":"item.name",
"userName":"item.userName",
"email":"item.email"
}
return this.httpClient.post(this.appConfig.apiEndpoint+'User/UpdateUser',
_data)
.pipe(map(response => response || {} as HttpEvent<any>));
}

Axios for Vue not uploading image to server

When I want to upload an image and send the other data using FormData. Axios seems to serialize the image. Therefore, when i upload the image using Axios, the image is inside the body's payload as a string. As a result, I'm unable to use Multer on the server side to retrieve the uploaded image from the request.
This is my Vue code:
export default () {
name: 'app',
data () {
image: ''
},
methods: {
onFileChange (e) {
var files = e.target.files || e.dataTransfer.files
if (!files.length) {
return
}
// console.log(files[0])
// var x = files[0]
return this.createImage(files[0])
// return new Buffer(x)
},
createImage (file) {
// var image = new Image()
var reader = new FileReader()
var vm = this
reader.onload = (e) => {
// vm.image = e.target.result
vm.image = file.toString('base64')
console.log(vm.image)
}
reader.readAsDataURL(file)
},
submitStaff () {
const formData = new FormData()
formData.append('file', this.image)
formData.append('name', this.data.name)
formData.append('username', this.data.username)
formData.append('password', this.data.password)
axios.post('api/myApiUrl', formData)
.then(function (response) {
console.log(response)
})
.catch(function (error) {
console.log(error)
})
}
}
<input type="file" #change="onFileChange">
Request Payload (Error with Vue)
Request Payload (Successful with Postman)
How do i fix this? Thank you!
I faced a problem related to it and in my case I was setting Content-Type as a default configuration for all my requests, doing this:
axios.defaults.headers.common['Content-Type'] = 'application/json [or something]';
And, as I remember, part of my solution was to remove this configuration to make the upload works. I just erased that line from my code and all requests worked well. As soon I removed it, I could notice that my headers request changed to this (see attached image and notice the Content-Type entry):
Another thing you should be alert is the field name to your <input type="file" name="file">. I have a java backend expecting a parameter named as "file", so, in my case, my input file HAS to be set as "file" on my HTML and on my server side, like this:
public ResponseEntity<Show> create(
#RequestParam("file") MultipartFile file,
RedirectAttributes redirectAttributes) { ... }
Observe the entry #RequestParam("file")...
And in the HTML file:
<form enctype="multipart/form-data" novalidate v-if="isInitial || isSaving">
<div class="well">
<div class="form-group">
<label>* Selecione o arquivo excel. O sistema fará o upload automaticamente!</label>
<div class="dropbox">
<input type="file" single name="file" :disabled="isSaving" #change="filesChange($event.target.name, $event.target.files); fileCount = $event.target.files.length"
accept="application/vnd.ms-excel" class="input-file">
<p v-if="isInitial">
Solte o arquivo excel aqui<br> ou clique para buscar.
</p>
<p v-if="isSaving">
Carregando arquivo...
</p>
</div>
</div>
</div>
</form>
You also can take a look at this tutorial, it my help you: https://scotch.io/tutorials/how-to-handle-file-uploads-in-vue-2
I hope it helps you!

Categories

Resources