I am using dropzonejs and using following code to initialize dropzone:
var myDropzone = new Dropzone("div#myId", { url: "/file/post"});
On the server side, I am using expressjs\nodejs & using following code:
fs.readFile(req.files.displayImage.path, function (err, data) {
// ...
var newPath = __dirname + "/uploads/uploadedFileName";
fs.writeFile(newPath, data, function (err) {
res.redirect("back");
});
});
problem is req.files is always coming as undefined.
I want to know when we upload a file, is there a way through developertoolbar to check the payload & confirm whether file is been sent or not?
Related
I have developed an API in express that returns text and images separately in two different calls, but for performance reasons I would like to return the text and image (probably in a blob object) in the same response.
Now I'm doing it with the res.send() and res.sendFile() methods but I haven't been able to read anything in the documentation about how to send both at the same time. How could I do it?
Examples of what I'm doing now:
async getImage(req, res){
//Doing things with req
let mypath = './foo/bar'
let file = new Blob(path.resolve(mypath), {type: 'image/png'});
return res.sendFile(file)
}
async getText(req, res){
// Doing things with req
return res.status(200).send({ message: 'foo' })
}
I am very new to this, so please bear with me-- I have currently have an operational google apps script on the backend of a google sheet that is generated from Google Form answers. I am essentially setting up a ticket form in google forms that will trigger the data in the corresponding sheet to be sent via api call to our ticketing system. It works great, but I am trying to optimize it currently. The goal is to take the json response I get using:
Logger.log(response.getContentText());
which provides me the following info:
Aug 9, 2020, 11:44:40 AM Info {"_url":"https://testticketingsystem.com/REST/2.0/ticket/123456","type":"ticket","id":"123456"}
and send another API call to send data to that new ticket.
Here's a code snippet:
var payload = {
"Subject": String(su),
"Content": String(as),
"Requestor": String(em),
"Queue": String(qu),
"CustomFields": {"CustomField1": String(vn), "CustomField2": String(vb), "CustomField3":
String(vg), "CustomField4": String(av), "CustomField5": String(ov), "CustomField6":
String(sd)}
}
var options = {
'method': 'post',
"contentType" : "application/json",
'payload': JSON.stringify(payload),
'muteHttpExceptions': true
}
var url = "https://testticketingsystem.com/REST/2.0/ticket?token=****************";
var response = UrlFetchApp.fetch(url,options);
Logger.log(response.getContentText());
} catch (error) {
Logger.log(error.toString());
}
}
After the ticket is created, how do I script the use of that ID number as a variable into my next api call?
Thank you!
UrlFetchApp.fetch returns a HTTPResponse, and if you expect JSON then you should be able to just use JSON.parse() to create an object from the text. (The JSON object is a standard JavaScript global object like Math; it is not Google Apps Script specific.)
If all goes well, you should just be able to use
var response = UrlFetchApp.fetch(url,options);
var data = JSON.parse(response.getContentText());
var id = data.id;
and then use that id for your next fetch().
Notes
If your literal response is indeed
Aug 9, 2020, 11:44:40 AM Info {"_url":"https://testticketingsystem.com/REST/2.0/ticket/123456","type":"ticket","id":"123456"}
you will run into trouble as everything until the { is invalid JSON (use a linter if you need to check yourself). But I'm assuming that was added by the console when you logged JSON, and not in the actual response itself.
JSON.parse() throws an error with invalid JSON, so you can use try/catch if needed.
You can also check the headers before you try to JSON.parse().
Here's an example that checks and handles issues, should they arise.
var type = response.getHeaders()["Content-Type"];
var text = response.getContentText();
if (type === "application/json") {
try {
var data = JSON.parse(text);
} catch (error) {
return Logger.log("Invalid JSON: " + response.getContentText(text));
}
} else {
return Logger.log("expected JSON, but got response of type: " + type);
}
// if we get to this line, data is an object we can use
I am trying to insert multiple images to couchdb via nano using express 4 and formidable. I can access and insert individual files without difficulty using formidable and nano, however, when I try to insert one file after another, I get conflict errors. I am very new to js and node, and I know my understanding of callbacks and asynchronous functions is limited. This is what I have at the moment. Any help would be greatly appreciated.
function uploadImage(req, res) {
var form = new formidable.IncomingForm(),
files = [],
fields = [];
uploadcount = 1;
form.on('field', function(field, value) {
fields.push([field, value]);
})
form.on('file', function(field, file) {
files.push([field, file]);
var docid = fields[0][1];
getrevision();
function getRevision(){
dbn.get(docid, { revs_info: true }, function(err,body, file){
if (!err) {
exrev = body._rev;
insertImage(exrev);
}else{
console.log(err);
}
});
}
function insertImage(exrevision){
var exrev = exrevision;
fs.readFile(file.path, function (err, data) {
if (err){
console.log(err);}else{
var imagename = docid + "_" + uploadcount + ".png";
dbn.attachment.insert(docid,imagename,data,'image/png',
{ rev: exrev }, function(err,body){
if (!err) {
uploadcount++;
}else{
console.log(err);
}
});
};
});
};
});
form.on('end', function() {
console.log('done');
res.redirect('/public/customise.html');
});
form.parse(req);
};
I found a solution by dumping the files first into a temporary directory, then proceeding to insert the files into couchdb via nano all within a single function. I couldn't find a way to pause the filestream to wait for the couchdb response, so this sequential method seems adequate.
This is a problem handling asynchronous calls. Because each attachment insert requires the doc's current rev number, you can't do the inserts in parallel. You must insert a new attachment only after you get a response from the the previous one.
You may use the promise and deferred mechanism to do this. But, I personally have solved a similar problem using a package called "async". In async, you can use async.eachSeries() to make these async calls in series.
Another point is about the revision number, you may just use the lighter weight db.head() function, instead of db.get(). The rev number is presented under the "etag" header. You can get the rev like this:
// get Rev number
db.head(bookId, function(err, _, headers) {
if (!err) {
var rev = eval(headers.etag);
// do whatever you need to do with the rev number
......
}
});
In addition, after each attachment insert, the response from couchdb will look something like this:
{"ok":true,"id":"b2aba1ed809a4395d850e65c3ff2130c","rev":"4-59d043853f084c18530c2a94b9a2caed"}
The rev property will give the new rev number which you may use for inserting to the next attachment.
I'm trying to write an image file to the localFolder storage. I want to write it specifically to the images/heroes/ folder inside the localFolder. Is there some way to do this with my existing code?
return WinJS.xhr({ url: fileToDownloadURL, responseType: 'blob' }).then(
function (response) {
var input = response.response.msDetachStream();
var filename = 'ms-appx:///local/images/heroes/image_name.png';
Windows.Storage.ApplicationData.current.localFolder.createFileAsync(filename,
Windows.Storage.CreationCollisionOption.replaceExisting).then(
function (file) {
return file.openAsync(Windows.Storage.FileAccessMode.readWrite).then(
function (output) {
return Windows.Storage.Streams.RandomAccessStream.copyAsync(input, output).then(
function () {
output.flushAsync().then(function () {
input.close();
output.close();
});
});
});
}
}
)};
I get this error message:
0x8007007b - JavaScript runtime error: The filename, directory name, or volume label syntax is incorrect.
WinRT information: The specified name (ms-appx:///local/images/heroes/image_name.png) contains one or more invalid characters.
I figured it out. For anyone wondering, you can call
getFolderAsync('SomeFolderName')
from the
Windows.Storage.ApplicationData.current.localFolder
instance. getFolderAsync() is like any promise function and will return with an error if the folder does not exist. From there you can run
createFolderAsync('SomeFolderName')
to create the folder, and then continue what you were doing. In my case it was better to create a function like writeFileAsync() and then call it depending on whether or not the folder exists first.
Keep in mind getFolderAsync() can only get one folder at a time, so something like
getFolderAsync('along/list/of/folders')
won't work. You'll have to chain together the getFolderAsync() calls together, I believe (correct me if I'm wrong!).
I need to post a file to Domino Server from a PhoneGap Application.
Here is the PhoneGap File Transfer example
// !! Assumes variable fileURI contains a valid URI to a text file on the device
var win = function(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
}
var fail = function(error) {
alert("An error has occurred: Code = " = error.code);
}
var options = new FileUploadOptions();
options.fileKey="file";
options.fileName=fileURI.substr(fileURI.lastIndexOf('/')+1);
options.mimeType="text/plain";
var params = new Object();
params.value1 = "test";
params.value2 = "param";
options.params = params;
var ft = new FileTransfer();
ft.upload(fileURI, "http://some.server.com/upload.php", win, fail, options);
//This is a PHP example - Domino would be like
// ft.upload(fileURI, "http://some.server.com/database.nsf/attachmentForm? createDocument", win, fail, options);
Does anyone know what needs to be done in Domino to get the file attachment that is being posted?
The easiest thing to do would be to create a form in Domino containing a File Upload control. You should be able to open the Domino form with a browser and see the generated html form that would normally be used. In there you will find all the info you need. This is of course dependent on the ft.upload method acting like an http multipart/form-data POST.