My Html file is -
<form method="post" [formGroup]="orderForm" enctype="multipart/form-data" (ngSubmit)="OnSubmit(orderForm.value)" >
<div class="form-group">
<label for="image">Select Branch Image</label>
<input type="file" formControlName="branchImg" (change)="onFileChange($event)" class="form-control-file" id="image">
</div>
</form>
and my .ts file is -
public orderForm: FormGroup;
onFileChange(event) {
const reader = new FileReader();
if (event.target.files && event.target.files.length) {
const [file] = event.target.files;
reader.readAsDataURL(file);
reader.onload = () => {
this.orderForm.patchValue({
branchImg: reader.result
});
};
}
}
ngOnInit() {
this.orderForm = this.formBuilder.group({
branchImg: [null, Validators.required]
});
}
and then submit the form.
I am supposed to get the image address and the upload that address in cloudinary
But when I am consoling the body in my nodejs app
it gives something like this-
branchImg: 'data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/7QCEUGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAGccAigAYkZCTUQwMTAwMGE4MjBkMDAwMD and so on.
I don't think that it is the images address. Can anyone tell me that what is this? and how to get that image's address which I will upload to cloudinary
As the Eric suggest -
my app.js code is
router.post('/branch',(req,res) =>{
const body = req.body;
const base64Data = body.branchImg.replace(/^data:image\/png;base64,/, "");
console.log(base64Data);
fs.writeFile("out.jpg", base64Data, 'base64', function(err,result) {
console.log(result);
});
});
it gives result as undefined
That basically is a base64 encoding of the image data. What you need to do after you get that is write that to a file, and then upload it to cloudinary
//this will write the base64 data as a jpg file to your local disk
require("fs").writeFile("out.jpg", base64Data, 'base64', function(err) {
//after you write it to disk, use the callback space here to upload said file
//to your cloudinary endpoint
});
Related
I generate HTML content to export PDF file using JsPDF library. Now, i need how to pass exported PDF file to server using angular 6. Thanks in advance
Here is my way to do it.
//HTML code
<input type="file" name="File Upload" id="txtFileUpload" accept=".csv"
(change)="changeListener($event)" />
//Component.ts
You have to import StaffService here:
changeListener($event: any) {
this.data = $event.target.files;
this.postFile(this.data);
}
postFile(inputValue: any): void {
this.file = inputValue[0];
this.staffService.uploadCSV(this.file).subscribe(response => {
//Do your next redirection or operation here
}, error =>{});
}
//StaffService.ts
public uploadCSV(file): Observable<any> {
const formdata = new FormData();
formdata.append('files', file);
return this.http.post(environment.apiUrlIp + this.urls.uploadCSVUrl, formdata, {
reportProgress: true,
responseType: 'json'
});
}
Let me know if you find any issue to integrate this code. Happy to help.
I'm new to React Hooks and honestly I'm not sure if this problem is related to Hooks or if I'm just doing something generally wrong.
I want to build a image uploader comonent that uses the HTML5 FileReader in order to show users the uploaded images before actually POSTing them.
Below is what I have so far.
Basically <div id="from-effect"></div> is currently my way of checking whether the images could be rendered.
I first wanted to fill this <div> without side effects (like <div>I have {files.length} files</div>) but this didn't react to changes at all.
The solution below with useEffect is reacting to changes.
However, if you try uploading a few images you will notice that quite often it's showing wrong results.
function FileUploader(props) {
const [files, setFiles] = useState([]);
const loadImageContent = (name, newFiles) => {
return (e) => {
newFiles.push({ name: name, src: e.target.result });
};
}
const handleUpload = async (e) => {
const newFiles = [];
for (const file of e.target.files) {
const reader = new FileReader();
reader.onload = loadImageContent(file.name, newFiles);
await reader.readAsDataURL(file);
}
setFiles(newFiles);
}
useEffect(() => {
console.log('in use Effect, files:', files);
const prevCont = document.getElementById("from-effect");
prevCont.innerHTML = `I have ${files.length} files`;
});
return <div>
<input
type="file" name="fileUploader" id="fileUploader"
accept="image/*" multiple="multiple"
onChange={handleUpload}
/>
<div id="from-effect"></div>
</div>;
}
What am I doing wrong?
Or even better, how can I implement this without side effects?
I am not sure I follow your ultimate goal, or what you mean when you say you want to show users the uploaded images before POSTing them - do you want to POST automatically, or do you want the user to click an "upload/save/POST" button or something?
Here is an example of how to display images:
Edit: made things a little more clear, added "save" button which shows an alert that contains data you could possibly use to POST back to your server. Also, added a method to "JSONify" the file metadata, since the way we are uploading files does not let us natively convert [object File] into JSON.
const { useState } = React;
function FileUploader(props) {
const [files, setFiles] = useState([]);
const getFileMetadata = file => {
/**
* The way we are handling uploads does not allow us to
* turn the uploaded [object File] into JSON.
*
* Therefore, we have to write our own "toJSON()" method.
*/
return {
lastModified: file.lastModified,
name: file.name,
size: file.size,
type: file.type,
webkitRelativePath: file.webkitRelativePath
}
}
const handleUpload = e => {
let newstate = [];
for (let i = 0; i < e.target.files.length; i++) {
let file = e.target.files[i];
let metadata = getFileMetadata(file);
let url = URL.createObjectURL(file);
newstate = [...newstate, { url, metadata }];
}
setFiles(newstate);
};
const handleSave = () => {
alert(`POST Files Here..\n\n ${JSON.stringify(files,null,2)}`);
}
return (
<div>
<input type="file" accept="image/*" multiple onChange={handleUpload} />
<div>
<button onClick={handleSave} disabled={!(files && files.length > 0)}>
Save Image(s)
</button>
</div>
{files.map(f => {
return (
<div>
<img src={f.url} height="100" width="100" />
</div>
);
})}
</div>
);
}
ReactDOM.render(<FileUploader />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
I wanted to upload images to products, and users. So im converting the image to base64 string and sending it. But when the selected image is large, the image is not getting uploaded as the base64 string is too large.
Here is the code:
Html
<input type="file" (change)="onFileSelected($event)">
<button type="submit" title="upload" (click)="uploadImage()"></button>
TS File
onFileSelected(event){
var files = event.target.files;
var file = files[0];
if (files && file) {
var reader = new FileReader();
reader.onload =this._handleReaderLoaded.bind(this);
reader.readAsBinaryString(file);
}
}
_handleReaderLoaded(readerEvt) {
var binaryString = readerEvt.target.result;
this.base64textString= btoa(binaryString);
console.log(btoa(binaryString));
}
Im just accepting the images on selection. So, is there any way to comress the image after selection or a way to reduce the base64 string so the image gets uploaded.
Thanks!! in advance.
In Angular you can upload image wihtout converting it into base64. Check this...
import { ViewChild } from '#angular/core';
export class yourComponent {
#ViewChild('fileInput') fileInput;
.
.
.
}
uploadImage(){
let fileBrowser = this.fileInput.nativeElement;
if (fileBrowser.files && fileBrowser.files[0]) {
console.log(fileBrowser.files[0]);
const formData = new FormData();
formData.append("userId", this.userId ); //appending userId in formData
formData.append("image", fileBrowser.files[0]); //appending image in formData
this.apiService.UploadImageMethod(formData)
.subscribe(
response=>{
console.log(response);
if(response.status == 'success'){
console.log(response);
}
},
err => {
this.imageErrorMsg = <any>err.message;
console.log(this.imageErrorMsg);
}
);
}
}
HTML:
<input type="file" id="fileInput" (click)="hideErrorMsg()" accept="image/*" #fileInput>
In API, you can get image data this way. (Php)
UploadImageMethod(){
$fileName = request()->image->getClientOriginalExtension();
$ext = strtolower(request()->image->getClientOriginalExtension());
}
Good Luck!!!
i deeply need help with this audio file upload to cloudinary issue I have had for several days now. I tried many times to make it work, but i am still struggling. I am a beginner backend developer, so please any help is appreciated.
It is an mp3 player App. When i upload a song, the title gets saved in DB, but the Audio isn't. This is the MP3 PLAYER page screenshot. It shows the title being saved and rendered from DB but not the audio file.
Audio upload form
<form class="ui form" action="/albums/<%= album._id %>/songs" method="POST" enctype="multipart/form-data">
<div class="field">
<label>Song Title:</label>
<input type="text" id="title" name="song[title]" placeholder="song title...." required>
</div>
<div class="field">
<label>Song file:</label>
<input type="file" id="song" name="audio" accept="audio/*" required>
</div>
<div class="field">
<input class="fluid ui green button" type="submit" id="submit" value="Enter">
</div>
Exit
</form>
Song model
var mongoose = require("mongoose");
//Album Schema
var audioSchema = new mongoose.Schema({
title: String,
audio: String,
date: {type: Date, default: Date.now()}
});
//exporting the Schema
module.exports = mongoose.model("Audio", audioSchema);
Backend code/ROUTE
var express = require("express"),
router = express.Router({mergeParams: true}),
middleware = require("../middleware"),
Album = require("../models/album"),
Song = require("../models/songs"),
multer = require("multer")
var storage = multer.diskStorage({
filename: function(req, file, callback) {
callback(null, Date.now() + file.originalname);
}
});
//uploader
var upload = multer({ storage: storage});
var cloudinary = require('cloudinary');
cloudinary.config({
cloud_name: 'proccess.env.CLOUDINARY_NAME',
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET
});
//Songs new Route
router.get("/albums/:id/songs/new", middleware.isLoggedIn, function(req, res) {
//find Album by id
Album.findById(req.params.id, function(err, album) {
if(err) {
console.log(err);
} else {
res.render("songs/new", {album: album});
}
});
});
//Song POST route
router.post("/albums/:id/songs", middleware.isLoggedIn, upload.single("audio"), function(req, res) {
cloudinary.uploader.upload(req.file.path, function(result) {
// add cloudinary url for the mp3 to the album object under audio property
req.body.song.audio = result.secure_url;
//find Album by ID
Album.findById(req.params.id, function(err, album) {
if(err) {
console.log(err);
res.redirect("/albums/" + req.params.id);
} else {
//Creating Album and saving it to DB
Song.create(req.body.song, function(err, song) {
if(err) {
console.log("Opps something went wrong!" + err);
res.redirect("back");
} else {
//save the song to DB
song.save();
//this saves the songs object inside
album.songs.push(song);
//save album
album.save();
res.redirect("/albums/" + album._id);
}
});
}
});
});
});
module.exports = router;
cloudinary.uploader.upload(req.file.path, resource_type: "video", function(result)
That's because you will need to use GridFS from MongoDB to store data from a file.
https://docs.mongodb.com/manual/core/gridfs/#use-gridfs
As you are using Mongoose, please check this module : https://www.npmjs.com/package/mongoose-gridfs
The mongoose-gridfs module wrap the gridfs-stream module, and seems to fit to binary data upload. If you want, you can still do it yourself, by following this tutorial : http://niralar.com/mongodb-gridfs-using-mongoose-on-nodejs/
I'm taking an image as an input from user using the below code
<input type="file" onChange={this.fileUpload}/>
I want to convert the image into URL.
This is what I used in fileUpload() function
fileUpload = (event) => {
let src = event.target.value.getAsDataURL();
this.setState({
image: src
});
}
Please let me know how to convert image into URL.
You can use the function below as ImageChange function and use the state variable imagePreviewUrl to preview the image.
_handleImageChange(e) {
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () => {
this.setState({
file: file,
imagePreviewUrl: reader.result
});
}
reader.readAsDataURL(file)
}
Add ref to your input tag, so you can access the dom for that element:
<input type="file" ref={this.myFiles} onChange={this.fileUpload}/>
fileUpload=()=>{
// Now get files in the FileList object
const files = this.myFiles.files
// Define what type of file to accept:
const accept = ["image/png"];
if (accept.indexOf(files[0].mediaType) > -1) {
this.setState({
image: files[0].getAsDataURL()
})
}
}
More infos: https://developer.mozilla.org/en-US/docs/Web/API/File/getAsDataURL