This question already has answers here:
How to post a file from a form with Axios
(9 answers)
Closed 2 years ago.
backend is expecting something like
{
"key" : "xyz"
}// and two files
I've tried the following code, but it always shows empty params passed in url
const obj = {
key : [this.state.key]
};
const json = JSON.stringify(obj);
const blob = new Blob([json], {
type: 'application/json'
});
const data = new FormData();
data.append("params", blob);
data.append("data1",this.state.file1)
data.append("data2",this.state.file2)
let res= await axios.get(url,data);
console.log(res)
You can't send data(body) by using get method. I think you need to use post method.
const obj = {
key : [this.state.key]
};
const json = JSON.stringify(obj);
const blob = new Blob([json], {
type: 'application/json'
});
const data = new FormData();
data.append("params", blob);
data.append("data1",this.state.file1)
data.append("data2",this.state.file2)
let res= await axios.post(url,data);
You cannot use formData with get, in order to send with body, file upload has to be a post request.
let res= await axios.post(url,data);
Related
export const getCharactersAsync = createAsyncThunk('getCharactersAsync', async (data) => {
const response = await axios.get('users', { params: { limit: data.limit } });
return response.data;
});
this code block allows me to control limit attribute.
export const getCharactersAsync = createAsyncThunk('getCharactersAsync', async (data) => {
const params = new FormData();
// const params = new URLSearchParams();
params.append('limit', data.limit);
const response = await axios.get('users', params);
console.log(response);
return response.data;
});
However I cannot control limit with using params.append. I tried URLSearchParams instead of FormData but still cannot manipulate limit attribute of the response. Why they differ from each other?
EDIT: This question has missleading information. I should have mention that i am using react-native. I found that react native doesn't fully support everything the web supports. So i need to install package called react-native-url-polyfill.Here is a github issues link
https://github.com/facebook/react-native/issues/23922#issuecomment-648096619
docs
params are the URL parameters to be sent with the request. Must be a plain object or a URLSearchParams object
It can't be FormData
Solution
You wanted to use { params }, not params
export const getCharactersAsync = createAsyncThunk('getCharactersAsync', async (data) => {
const params = new URLSearchParams();
params.append('limit', data.limit);
const response = await axios.get('users', { params });
console.log(response);
return response.data;
});
Hello All I hope All Are Doing Well
I have A issue I am uploading multiple images in Cloudinary via ReactJs
Here Is Input Field
<input
type="file"
className="form-control"
required
onChange={(e) => setImages(e.target.files)}
multiple
/>
OnChange I'm storing all files on a state given below
const [images, setImages] = useState([]);
Now I am looping the state and uploading each file to Cloudinary and extracting the URL of each Image code is given below
for (const file of images) {
async function upload() {
const formData = new FormData();
formData.append("file", file);
formData.append("upload_preset", "DummyPreset"); // Replace the preset name with your own
formData.append("api_key", "0300545648961"); // Replace API key with your own Cloudinary key
// Make an AJAX upload request using Axios (replace Cloudinary URL below with your own)
await axios
.post(
"https://api.cloudinary.com/v1_1/Dummycloud/image/upload",
formData,
{
headers: { "X-Requested-With": "XMLHttpRequest" },
}
)
.then((response) => {
const data = response.data;
const fileURL = data.secure_url; // You should store this URL for future references in your app
console.log(fileURL);
});
}
upload();
}
Here I'm able to extract each link As fileURL and consoled it
console.log(fileURL);
To See The Output Please click the Link it will redirects you to the image Outputimage
As You Can see all URLs Are Extracted Now I want to push All Extracted URLs into an Array And Wants to send them to Express Server where I'll store them into DB
Please Let Me Know How Store All URLs into a state array whenever any URL extracted it'll be stored into That array
Here's The Solution
Thanks For Contribution
var ImagesUrlArray = [];
for (const file of image) {
async function upload() {
const formData = new FormData();
formData.append("file", file);
formData.append("upload_preset", "DummyPreset"); // Replace the preset name with your own
formData.append("api_key", "0300545648961"); // Replace API key with your own Cloudinary key
// Make an AJAX upload request using Axios (replace Cloudinary URL below with your own)
await axios
.post(
"https://api.cloudinary.com/v1_1/Dummycloud/image/upload",
formData,
{
headers: { "X-Requested-With": "XMLHttpRequest" },
}
).then((response) => {
const data = response.data;
var fileURL = data.secure_url; // You should store this URL for future references in your app
ImagesUrlArray = [...ImagesUrlArray];
ImagesUrlArray.push(fileURL);
if (ImagesUrlArray.length === image.length) {
const res = axios
.post("http://localhost:5000/register", {
fullname: Data.fullname,
email: Data.email,
pass: Data.pass,
cpass: Data.cpass,
phone: Data.phone,
imagee: ImagesUrlArray,
})
.then((response) => response);
setdataa(res);
}
});
}
upload();
}
// this function returns a Promise
const uploadFile = (file) => {
const formData = new FormData();
formData.append(stuff);
return axios.post('some/path', formData).then(response => response.data.secure_url);
};
Promise.all(images.map(uploadFile)).then(fileURLs => storeFileURLs(fileURLs))
The below code is what take final action to save the data to the target DB.
const onFileUpload = (e) => {
const files = Array.from(e.target.files);
const formData = new FormData();
formData.append('attachable_type', attachableType);
formData.append('attachable_id', attachableId);
if (files.length > 0) {
const file = files[0];
formData.append('file', file);
upload(dispatch, {
body: formData,
}).then(() => {});
}
};
Now I am building an offline app, where when no internet is available I would like to save this request to indexdb. I have the whole setup. All I want to know how can I save a FormData instance to indexdb so that I can later fetch it from indexdb and send it to server for permanent storage. I need some ideas. I tried some google but I don't see any direct answer to the following question. I am using idb npm plugin. The below update function I will be using to as an interface to talk to the db.
export async function update(attrs) {
const db = await createAppDB();
const tx = db.transaction('attachments', 'readwrite');
const store = tx.objectStore('attachments');
store.put(attrs);
await tx.done;
}
You could extract the FormData through the Body.formData() method, and then retrieve its content by getting this FormData's entries and store these to IDB:
(async () => {
// in ServiceWorker while disconnected
const request = buildRequest();
// extract the FormData
const fd = await request.formData();
const serialized = {
url: request.url,
method: request.method,
mode: request.mode,
body: [ ...fd ]
// you may need more fields from request
};
// you can now store the entries in IDB
// here we just log it
console.log( "stored", serialized );
// and to build back the Request
const retrieved = { ...serialized };
const new_body = new FormData();
for( let [ key, value ] of retrieved.body ) {
new_body.append( key, value );
}
retrieved.body = new_body;
const new_request = new Request( retrieved );
// fetch( new_request );
// remember to remove from IDB to avoid posting it multiple times
console.log( "sent", [...new_body] );
} )();
// returns the same kind of Request object a ServiceWorker would intercept,
// whose body is a FormData
function buildRequest() {
const fd = new FormData();
fd.append( "some-key", "some-data" );
fd.append( "the-file", new Blob( [ "hey" ] ), "file.txt" );
return new Request( "", { method: "POST", body: fd } );
}
Too bad we can't just put POST requests in the Cache API, it would have been a lot cleaner...
As far as I know, you cannot store any FormData into IndexedDB directly. In my case, I had to implement photo uploading for an offline app. I saved images into IndexedDB in base64 format with some other data and then uploaded them on the server once the internet connection is restored.
In my application, the user uploads a CSV file in the website, and I need to update the file content (add a few columns) and send it to an API.
So far, I am able to read the file, and transform the CSV content into a JSON object, but I'm stuck in the process of updating the file content and sending it to the API (which needs to receive an object of type File). However, the way that I found is transforming the CSV into an encodeURI.
This is the code:
import { post } from "axios";
class UploadAdmin extends Component {
constructor(props) {
super(props);
// ...
}
onFormSubmit(e) {
if (this.state.file != null) {
e.preventDefault();
// adding the missing columns to the JSON object
const csvObject = this.state.parsedCsvFile;
csvObject["Campaign Name"] = this.state.campaign_name;
csvObject["Campaign Code"] = this.state.campaign_code;
const rows = [Object.keys(csvObject), Object.values(csvObject)];
let csvContent =
"data:text/csv;charset=utf-8," +
rows.map((e) => e.join(";")).join("\n");
// creating CSV file (here the error is happening, since I need to create an object
// with File type to send to the fileUpload() function, but I'm creating an URI)
var newFile = encodeURI(csvContent);
this.fileUpload(newFile)
.then((resp) => {
this.onClear();
this.setState({ modal: true, tipo: "success" });
this.props.getListImport();
})
.catch((error) => {
// handling errors...
} else {
this.onClear();
}
}
fileUpload(file) {
const BASE_URL = `${window.REACT_APP_URL}`;
const formData = new FormData();
formData.append("file", file);
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
return post(`${BASE_URL}/file`, formData, config);
}
Thanks in advance.
To be honest I'm still confused about this, but I don't have time right now. The following may or may not work:
fileUpload(file) {
const BASE_URL = `${window.REACT_APP_URL}`;
const searchParams = new URLSearchParams();
searchParams.append("file", file);
const config = {
headers: {
"content-type": "multipart/form-data",
},
};
const file = new File(searchParams.toString(), "my-file",
{ type: "multipart/form-data" });
return post(`${BASE_URL}/file`, file, config);
}
I changed the FormData to a URLSearchParams. They seem to be very similar types, but URLSearchParams has a toString method which I've called. Then I made it into a File because you said this was necessary, although I'm not convinced that it is. I also renamed it from formData to searchParams.
I'm saving an image file locally so I can ready it using fs.createReadStream() and append it to my FormData to send it to a REST api. Like this: (I'm using the trello api https://developer.atlassian.com/cloud/trello/rest/#api-cards-id-attachments-post)
const fetch = require('node-fetch');
const Jimp = require('jimp');
const FormData = require('form-data');
// Save file locally
await Jimp.read(imagePNGURL).writeAsync(savedImagePath);
// Append it to the formdata using fs.createReadStream
const formData = new FormData();
formData.append('file', fs.createReadStream(savedImagePath));
// Send formData to api and image gets saved correctly
await fetch('TrelloUrl', { method: 'POST', body: formData })
Now I want to do the same thing but without saving the file locally but by using the image buffer. I've tried the following but I can't seem to make it work:
const fetch = require('node-fetch');
const Jimp = require('jimp');
const FormData = require('form-data');
const stream = require('stream');
// Save file to Buffer
const buffer = await Jimp.read(imagePNGURL).getBufferAsync('image/png');
// Convert buffer to stream
const bufferStream = new stream.PassThrough();
bufferStream.end(buffer);
// Try to append it to the formdata and send it to the api
const formData = new FormData();
formData.append('file', bufferStream); // Results in 400 Bad Request
formData.append('file', bufferStream.read()); // Results in empty image being uploaded
await fetch('TrelloUrl', { method: 'POST', body: formData })
---------
// Also tried to convert the buffer to stream like this:
const { Readable } = require('stream');
const bufferToStream = (buffer) => {
const stream = new Readable();
stream.push(buffer);
stream.push(null);
return stream;
};
formData.append('file', bufferToStream(buffer)); // Results in 400 Bad Request
formData.append('file', bufferToStream(buffer).read(); // Results in empty image being uploaded
How can I convert the buffer correctly to a fs.ReadStream() object so I can send it successfully to the api?
Or are there better ways to approach this?
All help is appreciated.
You can get the stream directly from the url using axios and append to form-data
const axios = require("axios")
const getImageStream = async (url) => {
const response = await axios.get(url, {responseType : "stream"});
if (response.status === 200) {
return response.data
}
}
const formData = new FormData();
formData.append('file', await getImageStream(imagePNGURL) );
set custom filename (set whatever name do you want) and content-type, worked for me
const formData = new FormData();
formData.append('file', bufferStream, {filename: 'photo.png', contentType: 'image/png');