You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I am running into a bit of a perplexing situation.
I parse and generate excel files as part of the model creation loop for my end users, so accordingly I take file uploads and pass them to my plugins thru the BlobClient.
In my frontend, I have a React class FileInput that uploads files to the BlobClient. However, I do not quite understand the interactions.
I have two cases:
1: The first version works correctly in all regards, except it caches the files with the same name. This is a problem for me, because the user can be editing their file and re-upload it, and the changes are not visible to the plugin as it sees the first uploaded version. This version creates an artifact using the createArtifact(fileName) function,
2: The second case directly uses putFile, and has a crippling issue: I cannot recover the information about the file (primarily, its name). This is inconvenient when the user uploads a file, and then they reopen the plugin config, and while the result is cached and ready to be ran without further interaction, I cannot display the filename, so the user thinks they must re-upload.
Here is a code sample of my component which interfaces with the BlobClient, and the two cases:
class FileInput extends React.Component {
@observable $state = {
uploaded: false,
fileName: '',
hash: null,
label: 'Choose a file',
artifact: null,
}
constructor(props) {
super(props);
const { BlobClient } = this.props.GME.classes;
const { logger } = this.props;
this.blobClient = new BlobClient({
logger: logger.fork('FileInput'),
uploadProgressHandler: this.uploadProgressHandler,
});
}
uploadProgressHandler(fName, e) {
// consumes e.percent if it's a number
}
componentDidMount() {
if (this.props.fileHash) {
this.recoverFileFromHash(this.props.fileHash);
}
}
onChange() {
if (typeof this.props.onChange === 'function')
this.props.onChange(this.$state.hash);
}
@action
reset() {
this.$state.uploaded = false;
this.$state.fileName = false;
this.$state.hash = null;
this.$state.label = 'Choose a file';
this.$state.artifact = null;
}
@action
finishedUpload(metadata) {
this.$state.uploaded = true;
this.$state.fileName = metadata.name;
this.$state.hash = fileHash;
this.$state.label = 'Change file';
}
// upload the file if they upload
// clear the current file if they cancel
@action
onFileChanged(event) {
event.stopPropagation();
event.preventDefault();
const files = event.target.files || event.dataTransfer.files;
if (files && files.length === 1) {
this.upload(files[0]);
} else {
this.reset();
}
}
recoverFileFromHash(fileHash) {
this.blobClient.getMetadata(fileHash)
.then((metadata) => {
this.finishedUpload(metadata);
})
.catch((err) => {
this.reset();
this.onChange();
});
}
/* FIRST VERSION, works correctly except caching */
@action
upload() {
this.reset();
// two files with the same `name` property will both return whatever file was uploaded first
const fileArtifact = this.blobClient.createArtifact(this.$state.fileName);
fileArtifact.addFileAsSoftLink(this.$state.fileName, file)
.then((metadataHash) => {
return (
fileArtifact.save()
.then(() => this.blobClient.getMetadata(metadataHash))
.then((metadata) => this.finishedUpload(metadata))
);
})
.catch((err) => {
console.log('Errors not handled?');
});
}
/* SECOND VERSION, doesn't hold file name or anything? */
@action
upload() {
this.blobClient.putFile(this.$state.filename, file)
.then((metadataHash) => {
// first way you might expect to get metadata:
this.blobClient.getArtifact(metadataHash)
/* fails like:
Errors not handled? Error: not supported contentType {
"name": "undefined",
"size": 26360,
"mime": "application/octet-stream",
"isPublic": false,
"tags": [],
"content": "4ca68d033dc2a590409baf2058ee70c11437aa45",
"contentType": "object",
"lastModified": "2019-05-06T23:48:19.329Z"
}
at webgme.classes.build.js:46378
at webgme.classes.build.js:5341
*/
// second way you might expect to get metadata:
this.blobClient.getMetadata(metadataHash)
/* succeeds, but returns a useless object, like:
{
"name": "undefined",
"size": 26360,
"mime": "application/octet-stream",
"isPublic": false,
"tags": [],
"content": "4ca68d033dc2a590409baf2058ee70c11437aa45",
"contentType": "object",
"lastModified": "2019-05-06T23:48:19.329Z"
}
*/
});
}
}
So, for my two cases, my questions are:
How to avoid this caching behavior of artifacts based on name? It occurs to me now that this artifact name could be a random UUID, which would possibly bust the caching. I'll try that.
Why does the BlobClient "not support" some filetypes when it still can handle their data correctly? I understand that you may be trying to avoid situations where files are passed around with incorrect content-type headers or something, but at least preserving the filename would likely make the BlobClient more versatile.
Thanks
The text was updated successfully, but these errors were encountered:
Okay, so I can confirm that I can avoid the problem I was having with artifacts with the same filename using cached versions by creating a random numeric ID instead of using the filename in the createArtifact call, which in some way solves my initial problem.
However, question 2 still stands out for me a bit, so I'll leave this open for a little dialogue around how I'm using the BlobClient and how you would anticipate it being used.
I am running into a bit of a perplexing situation.
I parse and generate excel files as part of the model creation loop for my end users, so accordingly I take file uploads and pass them to my plugins thru the BlobClient.
In my frontend, I have a React class FileInput that uploads files to the BlobClient. However, I do not quite understand the interactions.
I have two cases:
1: The first version works correctly in all regards, except it caches the files with the same name. This is a problem for me, because the user can be editing their file and re-upload it, and the changes are not visible to the plugin as it sees the first uploaded version. This version creates an
artifact
using thecreateArtifact(fileName)
function,2: The second case directly uses putFile, and has a crippling issue: I cannot recover the information about the file (primarily, its name). This is inconvenient when the user uploads a file, and then they reopen the plugin config, and while the result is cached and ready to be ran without further interaction, I cannot display the filename, so the user thinks they must re-upload.
Here is a code sample of my component which interfaces with the BlobClient, and the two cases:
So, for my two cases, my questions are:
content-type
headers or something, but at least preserving the filename would likely make the BlobClient more versatile.Thanks
The text was updated successfully, but these errors were encountered: