In electron, how to upload a file from it's full filename - javascript

In my electron app I have a button that says "upload contract".
When clicked it looks from the stored contract's filename ie. /home/users/filename.docx and gets it (no need for a dialog window).
Now, I have problems uploading this file as a multipart form data while using axios.
I've read about this issue, asking for file upload on axios which led to this pull request for file upload on browser and this pull for uploading in node.js.
I've read through the issues and comments applying bit by bit but seems to have troubles getting the real file uploading right using axios.
Here is what I have been doing.
Upload as browser
export function generateContract(fileUrl, customer) {
const data = new FormData()
const file = fs.createReadStream(fileUrl)
data.append('names', customer.names)
data.append('email', customer.email)
data.append('contract', file)
return data
}
//- In between generateContract & uploadFile function some function
//- gets the generatedContract data & push it to uploadFile for axios uploading.
//- In API file.
export function uploadFile(formData) {
return checkConnetion()
.then(() => {
return axios.post(emailUrl, formData)
})
.catch(() => {
return axios.post(emailUrlOffline, formData)
})
}
In generatedContract I'm using FormData that (I assume) is a global function in browsers to create a form instance for uploading files.
I'm also using fs.createReadStream cause without it my file upload looks like an object with three strings (the fileUrl gets to be a normal string).
However, uploading like this and console.loging my request body from my local server I get a hopeless
{ names: 'Mwajuma Salmin',
email: 'sammwaj#yahoo.com',
contract: '[object Object]' }
The contract file is `[object Object]'.
Uploading as node.js
Everything is the same, except I'm using npm's form-data.
Output is.
{ '[object FormData]': '' }
Where am I messing up?
I tried uploading with postman and manually selected the file to upload as form-data and that other data (email & names), it was all successful!
Output.
{ names: 'maotora',
contract:
[ File {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
size: 11609,
path: '/tmp/upload_0af5c038e147888f0a7b89ad4784a4dc',
name: 'Don Joe_08-06-17\'s_contract-for Plot 011.pdf',
type: 'application/pdf',
hash: null,
lastModifiedDate: 2017-09-28T18:56:31.083Z,
_writeStream: [Object] } ] }
I can't use form uploading in the app (just the button to upload without opening a dialog to select file) I only have the filename to the file.
Thanks.

This question has been open for a sometime since I couldn't solve the issue with axios and had to use superagent for a while.
However, now that it's solved and can use axios just fine, this is how I did solved it on my project.
//- Correctly placing a file_Url into FormData
export function generateContract(url, {names, email}) {
const file = {
uri: url,
name: _.replace(url, /\.[doc,docx,odt,]+$/, ''),
type: 'docx'
}
const formData = new FormData()
formData.append('contract', file)
formData.append('names', names)
formData.append('email', email)
return formData
}
//- 1. Calling generateContract method
//- 2. Passing the formdata (from method 1) to sendEmail
const contractData = generateContract(contractUrl, payload)
const response = yield sendEmail(contractData)
//- The sendEmail function that makes requests using axios
export function sendEmail(contractData) {
return checkConnetion()
.then(() => {
return axios.post(emailUrl, contractData)
})
.catch(() => {
// return axios.post(emailUrlOffline, contractData)
userLog('Cannot connect to server, check your internet settings.', 'Connection Error', 'error')
})
}

Related

How to convert form-data image binary to something I can covnert to .webp format?

My goal is to have a UI where
a user can upload an image
image is converted to webp
image is stored in my Google Cloud Storage
Right now, I have a NextJS using Material UI frontend which uses the following to convert the image for use in form-data then sends through an API to the backend.
frontend.tsx
...
async function handlePostCallConvertToWebP(imageFile: any): Promise<any> {
const formData = new FormData()
formData.append("image", imageFile, imageFile.name)
console.log(formData.getAll("image"))
const response: Response = await fetch(`${host}/api/image`, {
method: "POST",
headers: { "Content-Type": "multipart/form-data" },
body: formData,
})
...
Then the npm package sharp should convert the file to webp.
pages/api/productImage/index.ts
...
import Sharp from "sharp"
export default function handler(req: NextRequest, res: NextResponse<Object>) {
console.log("METHOD: ", req.method)
if (req.method == "POST") {
convertToWebP(req.body)
res.status(200).send({ message: "Success" })
} else {
res.status(404).send({ message: "POST only supported" })
}
}
function convertToWebP(imageFile: any) {
const converted = Sharp(imageFile)
.webp()
.toFile("out.webp") // I'm just outputting to local directory
.then((x: any) => console.log(x))
}
Then the webp image will be uploaded to Storage (not shown, not important to this).
The frontend code works as intended but I'm stuck on capturing the the body of the request and turning it into something that sharp will understand. I've tried to convert the binary body with Buffer.from() but that doesn't take the body.
I'm having a pretty hard time on this so I'd appreciate being pointed in the right direction.

multipart/form-data not being automatically set with axios in React Native

When attempting to upload a file to Amazon S3 using axios, I have been encountering a very strange issue. Normally, in a web browser, when FormData has binary data in it, the Content-Type header automatically gets set to multipart/form-data; boundary=<some random string>. However, I have been completely unable to achieve that in React Native (testing on an iOS device). The Content-Type is automatically set to application/json, and thus not being detected as a correctly formatted body when uploading to Amazon S3. I have tried specifying a blob in the file parameter in FormData instead of the URI to the file as well to no avail. I have appended my code below, any advice would be very much appreciated.
const uploadFileToS3 = (
presignedPostData,
file) => {
// create a form obj
const formData = new FormData();
// append the fields in presignedPostData in formData
Object.keys(presignedPostData.fields).forEach(
key => {
formData.append(
key,
presignedPostData.fields[key],
);
},
);
// append the file and uplaod
const getBlob = async () => {
const img_url = previewPath;
let result = await fetch(img_url);
const blob = await result.blob();
formData.append('Content-Type', 'image/jpeg');
formData.append('file', {
uri: previewPath,
type: 'image/jpeg',
name: 'test.jpeg',
});
console.log(formData, 'wild');
// post the data on the s3 url
axios
.post(presignedPostData.url, formData)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error.response);
});
};
getBlob();
};

How to download an encoded asset (any type of file) in React?

In my React app, I have an API to get the file by sending the file URL. After I receiving the file, I need to download it as the original file. This should be applicable to any type of file. When I call the API, I'm getting the encoded text of the file from the back end. I'm using the react-file-saver module to download the file. The problem is, the module downloads a text file instead of the real file.
This is how the GET API response looks
IHDRÄõWìã¢sRGB®Îé–eXIfMM*>F(‡iNÄ õASCIIScreenshotÞK| pHYs%%IR$ðÖiTXtXML:com.adobe.xmp<x:xmpmeta xmlns:x="........
This is the Function for the download
import { saveAs } from 'file-saver';
downloadFile = (url) => {
API.get(`/main/download?fileUrl=${url}`, { headers: { 'Accept': 'application/*' } })
.then(res => {
var file = new File([res.data], { type: "text/plain;charset=utf-8" });
saveAs(file);
})
.catch((err) => {
console.error("AXIOS ERROR: ", err);
})
}
How can I solve this?

Firebase admin get file from Storage with temporary download url

I am trying implement a function which provides a temporary file url for downloading. Right now user enter his/her email id and function response with a file url. To fetch the file I am using firebase-admin SDK to access storage bucket and retrive a file.
Problem : Right now everything is working fine but the file URL is not working.. I am getting the error: Anonymous caller does not have storage.objects.get access to the Google Cloud Storage object.
app.post('/getFile', (req, res) => {
let email = req.body.mail;
if (micro.validateEmail(email)) {
micro.checkIfUserExists(admin, email)
.then(data => {
storage.file('form.pdf')
.getMetadata()
.then(fileRes => {
sendMail.send(email, fileRes[0].mediaLink).then(msg => {
res.send({
uri: fileRes,
res: msg,
mail: email,
data: data
})
});
});
});
}
});
Edit:
So I have found that I could use getSignedURL to get a url but I don't know how to specifiy a file path, for which I url is needed.
const bucket = storage.bucket();
//-
// Generate a URL that allows temporary access to list files in a bucket.
//-
const config = {
action: 'list',
expires: '03-17-2025'
};
//-
// If the callback is omitted, we'll return a Promise.
//-
bucket.getSignedUrl(config).then(function(data) {
const url = data[0];
});
Edit 2
So I have found that you can specify the file by specifying the bucket.file('')
const bucket = storage.bucket().file('form.pdf');
But now I have another problem. I am getting this error in firebase function log
Permission iam.serviceAccounts.signBlob is required to perform this operation on service account

How do I upload a string as a file to Google Drive?

here's my problem :
I want to create a Google Sheets extension in which I basically extract data from a sheet in Google Sheets, that I modify using methods in node JS.
Then, having the data that I modified in a string, I want to upload that string into the client's Drive, in a csv or xml file. Therefore I don't have a local file that I can use to upload the file, just a string variable.
How do I upload that string ?
Thanks a lot, that's my first app and I'm struggling a bit.
Code
const {google} = require ('googleapis');
const keys = require ('./keys.json');
const client = new google.auth.JWT(
keys.client_email, null,
keys.private_key,
['googleapis.com/auth/drive'],
'https://www.googleapis.com/…'
);
client.authorize(function(err, tokens){
if (err){
console.log(err);
return
} else {
console.log('Connected');
gsrun(client);
}
});
async function gsrun(cl) {
const gsapi = google.sheets({version: 'v4', auth: cl});
}
You have to set your file's metadata and the data it will contain (it's important the MIME type for this case must be text/csv) and the file's body will be a simple string. This code will help you taking into consideration you already did the OAuth process and have the string you want to insert:
module.exports.init = async function (){
// Before calling the API, build your own Drive service instance
// In the second argument, you must pass your own string message
const pro = await uploadSimpleString(drive, null);
console.log(pro);
}
uploadSimpleString = (drive, message) => {
// Set file metadata and data
message = message || 'This is a simple String nice to meet you';
const fileMetadata = {'name': 'uploadSimpleStringt.csv'};
const media = {
mimeType: 'text/csv',
body: message
};
// Return the Promise result after completing its task
return new Promise((resolve, reject) => {
try{
// Call Files: create endpoint
return drive.files.create({
resource: fileMetadata,
media: media,
fields: 'id'
},(err, results) => {
// Result from the call
if(err) reject(`Drive error: ${err.message}`);
resolve(results);
})
} catch (error){
console.log(`There was a problem in the promise: ${error}`);
}
});
}
Notice
To test this code, run it in your CLI using this command:
node -e 'require("./index.js").init()'
Where index.js is your file's name and init() is your main function.
Docs
For more info, please check these links and also consider using the [google-drive-api] tag in that way, there are more chances to receive help because more people will be able to find your question.
How to get Help
Files: create
G Suite documents and corresponding export MIME types

Categories

Resources