FilePond,Laravel restore uploaded temporary files on validation failure - javascript

after searching a lot here and there I am going to put my question here . If any body can help out in this regard . Let me explain the things I am working on Laravel and Filepond .
Filepond upload and revert is working perfectly but I am facing problem in restoring the file back if the validation gets failed i-e restore the file on filepond.
files: [{
source: 'filename',
options: {
type: 'limbo',
},
}, ],
the source is coming from laravel controller function
FilePond.setOptions({
server: {
process: './filepond-upload',
revert: './filepond-delete',
restore: './filepond-restore',
// restore: {
// url :'./filepond-restore/?id=',
// method :'GET',
// },
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
'Access-Control-Expose-Headers': 'Content-Disposition,'
// 'Access-Control-Expose-Headers': 'Content-Disposition',
}
}
});
Controller function -
public function filepondRestore(Request $request, string $id) {
$abc = ('/posts/tmp/post6399a6ba2ea280.18814893/presentation_1.png');
return response()->json('', 200, [
'Content-Type' => 'image/png',
'Content-Disposition' => 'inline;
filename="'.$abc.'"',
]);
}
but either get 302 redirection or 500 server error.
If any body have implemented such kind of functionality I ll be thankful for sharing.
Thanks in advance.
Happy Coding

Related

Vimeo API Upload Progress

I'm using the Vimeo API to upload videos and am trying to track the progress of the upload.
The documentation here is pretty straightforward:
https://developer.vimeo.com/api/upload/videos
However, I can't seem to figure out how to retrieve Upload-Length and Upload-Offset from the HEAD response.
I call the "uploadVideo" function below to upload the video to Vimeo (this function does as it should). I then call the "getProgress" function and this is where things go awry. I've tried many variations of this code, but none have worked.
async function uploadVideo(upload_link : string) {
const uploadResponse = await fetch(upload_link, {
method: 'PATCH',
headers: {
'Tus-Resumable': '1.0.0',
'Upload-Offset': '0',
'Content-Type': 'application/offset+octet-stream'
},
body: accepted
});
}
async function getProgress(upload_link : string) {
const progress = await fetch(upload_link, {
method: 'HEAD',
headers: {
'Tus-Resumable': '1.0.0',
'Accept': 'application/vnd.vimeo.*+json;version=3.4'
},
});
const currentProgress = await progress;
console.log(currentProgress);
// if (currentProgress.upload_length != currentProgress.upload_offset) {
// getProgress(upload_link)
// }
}
If I await progress.json(), I get a SyntaxError: Unexpected end of JSON input
I'm somewhat surprised that there are no up-to-date JavaScript examples of this process out there on the interwebs. Any assistance would be greatly appreciated.
Thank you for your time.
As #Clive pointed out above, to access the necessary headers, one would use:
uploadLength = progress.headers.get('upload-length');
uploadOffset = progress.headers.get('upload-offset');
This answers my specific question.
However, if you're only using the Vimeo API, you'll find that there's another challenge once this is complete. In the original code posted above, you'll never be able to track the progress of the upload with a HEAD request because the "upload-offset" value is always 0 until the initial PATCH request is completed, i.e. it's 0 until the PATCH request is complete and once it's complete it jumps directly to 100%.
To get around this issue, I decided to use "tus-js-client." So, if you've made it to where my code above leaves off, instead of using the above functions you could just pass the link (in this example, "upload_link") and the file (in this example, "accepted") to:
async function uploadVideo(upload_link : string) {
// Create the tus upload similar to the example from above
var upload = new tus.Upload(accepted, {
uploadUrl: upload_link,
onError: function(error) {
console.log("Failed because: " + error)
},
onProgress: function(bytesUploaded, bytesTotal) {
var percentage = (bytesUploaded / bytesTotal * 100).toFixed(2)
console.log(bytesUploaded, bytesTotal, percentage + "%")
},
onSuccess: function() {
console.log("Download %s from %s", upload.file.path, upload.url)
}
})
// Start the upload
upload.start()
}
And here's the server-side code to get the "upload_link":
export const actions: Actions = {
upload: async ({ request }) => {
const uploadFormData = await request.formData();
const accepted = uploadFormData.get('accepted-file') as File;
const response = await fetch(`https://api.vimeo.com/me/videos`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `bearer ${import.meta.env.VITE_VIMEO_ACCESS_TOKEN}`,
'Accept': 'application/vnd.vimeo.*+json;version=3.4'
},
body: JSON.stringify({
upload: {
"approach": "tus",
"size": accepted.size
}
})
});
const dataResponse = await response.json();
return {
upload: dataResponse.upload
}
}
}
This server response is returned to a client-side "handleSubmit" function, which in turn calls the "uploadVideo" function, like so uploadVideo(result.data.upload.upload_link).
I was initially using "vimeo-upload" to accomplish this. The problems with vimeo-upload are (1) it exposes your access token to the browser and (2) the code base is outdated. I'd advise to stay away from vimeo-upload at all costs!
For what it's worth, this is a SvelteKit implementation.
If you're using SvelteKit, best to not use an import.meta.env.VITE prefixed environment variable; it should be a "private" environment variable as shown here:
https://joyofcode.xyz/sveltekit-environment-variables
I had such a hard time figuring out how to do this. I hope that this example will help someone in the future.

How to upload a file along with text using fetch in react native?

I'm trying to upload a file to the server using react-native-document-picker. The problem I'm facing is I don't know how to upload the file along with a text.In my app there is a portion for file upload also there is an area for writing some text.Then it will get uploaded to the server.So I've done the following.But I'm getting this error after submitting to server
unhandled promise rejection unsupported BodyInit type
updated portion of code
filepick = () => {
DocumentPicker.show({
filetype: [DocumentPickerUtil.images()],
}, (error, res) => {
if (error == null) {
console.log(
res.uri,
res.type, // mime type
res.fileName,
res.fileSize
);
this.setState({
img_uri: res.uri,
img_type: res.type,
img_name: res.fileName
})
} else {
Alert.alert('Message', 'File uploaded failed');
}
});
};
onPressSubmit() {
const data = new FormData();
data.append('file', { uri: this.state.img_uri, type:
this.state.img_type, name: this.state.img_name })
data.append('comment', { text: this.state.text });
AsyncStorage.getItem("userdetail").then(value => {
fetch(GLOBAL.ASSN_URL +`${this.props.id}`, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
'Authorization': value
},
body: data
}).then((response) => {
return response.text()
}).then((responseJson) => {
var result = responseJson;
console.log(result);
});
})
}
The function filepick() is called after choosing a file from your device.Please help me to find a solution.How do I upload this to server also how to send text without stringifying it?
body: ({
file: this.state.file,
comment: this.state.text
})
Why are you wrapping body in brackets? Removing them might fix it.
Also see this, https://github.com/facebook/react-native/issues/6025 you might want to stringify the body object, since your content type is not application/json
body: JSON.stringify({
file: this.state.file,
comment: this.state.text
})
Edit
From comments we now know the following
1) You are uploading a file separately.
2) The upload response contains information about the file
3) You are saving the entity in separate server call
4) You need to save file with that entity
The solution below assumes that you have full control over server and you are also handling the file uploading endpoint. Here is the solution
You basically do not need to upload the whole file again with your entity since it is already uploaded on server, all you need to do is to save the reference of the file with entity. Their are two ways to save the reference
1) Just save either the fileName or fileUrl in your entity table and then store the name or url with entity so it will look like this
{
id: 1,
name: 'Cat',
picture: // url or name of picture
}
2) Save the uploaded file in different table, then save the id of the file with your entity, and when you fetch entities get the related file. However if the relationship between entity and file is one to many as in one entity can have many files then you will first need to save the entity and then upload the files with reference of entity. This way your entity will look like this
{
id: 1,
name: 'Cat',
pictures: [{fileName: 'cat1'}, {fileName: 'cat2'}]
}

Dropzone send empty

I have a dropzone setup with the following script:
<script>
Dropzone.options.myDropzone = {
url: 'assets/PHP/createNieuws.php',
autoProcessQueue: false,
uploadMultiple: true,
parallelUploads: 1,
maxFiles: 1,
maxFilesize: 1,
acceptedFiles: 'image/*',
addRemoveLinks: true,
createImageThumbnails: true,
init: function () {
dzClosure = this; // Makes sure that 'this' is understood inside the functions below.
this.on("success", function (file, responseText) {
console.log(responseText);
});
// for Dropzone to process the queue (instead of default form behavior):
document.getElementById("submit").addEventListener("click", function (e) {
// Make sure that the form isn't actually being sent.
e.preventDefault();
e.stopPropagation();
if (dzClosure.getQueuedFiles().length > 0) {
dzClosure.processQueue();
} else {
dzClosure.uploadFiles([{ name: 'nofiles' }]); //send empty
}
});
//send all the form data along with the files:
this.on("sendingmultiple", function (data, xhr, formData) {
formData.append("titel", jQuery("#titel").val());
formData.append("artikel", jQuery("#artikel").val());
});
}
}
</script>
And i also have a file named default.png on my server. I would like dropzone to refer to default.png if no image is detected. As you can see i've tryed this solution already to no succes: https://stackoverflow.com/a/41044001/6396380
This returns the following error in my chrome console:
dropzone.js:1497 Uncaught TypeError: Cannot read property 'filename' of undefined
My dropzone version is 5.1.0 .
Any idea's on how to fix this?
This happens because the new version assumes that there is a file.upload object with filename. Changing your mock file to
{ name: 'nofiles', upload: { filename: 'nofiles' } }
should do the trick.
You should also upgrade to 5.1.1 because it solves a bug related to this.
For people having errors on firefox due to append method while using uploadFiles function but still wants to get that phat xhr request submitted with everything handled for you I suggest instead of using
dropzone.uploadFile({
name: 'nofiles',
upload: {
filename: 'nofiles'
}
})
to use
dropzone._uploadData(
[
{
upload: {
filename: ''
}
}
],
[
{
filename: '',
name: '',
data: new Blob()
}
]
);

How to Upload a Google Apps Script via the Google Drive API (NodeJS)

I'm trying to use the Google API NodeJS client to upload a Google Apps Script to my drive. I am following the directions in the docs, but when the file gets uploaded to my drive, I can only upload it as plain text and not as an Apps Script.
function uploadAppScript(auth) {
return new Promise(function(resolve, reject) {
var drive = google.drive('v3')
drive.files.create({
auth: auth,
resource: {
name: 'myscript',
mimeType: 'application/vnd.google-apps.script'
},
media: {
mimeType: 'text/plain',
body: fs.createReadStream('src/myscript.gs')
},
}, function(err, result){
... //not relevant
})
})
}
The media uploads section of the README does not specify how to upload anything other than a png.
If I change the mimeType in the media object to anything other than text/plain I get the following (uninformative) error:
code: 400,
errors:
[ { domain: 'global',
reason: 'badRequest',
message: 'Bad Request' } ] }
Any ideas on how to get Drive to recognize this as an Apps Script and not a plain text file? Or is this something broken on the NodeJS client's end?
So this is apparently a bug with the google-api-nodejs-client but a maintainer of the library was able to assist me where the documentation could not. The following will allow you to upload a .gs file to Google Drive properly:
drive.files.create({
resource: {
name: 'myscript.gs',
mimeType: 'application/vnd.google-apps.script+json'
},
media: {
mimeType: 'application/vnd.google-apps.script+json',
body: JSON.stringify({
files: [
{
source: fs.readFileSync('src/myscript.gs', { encoding: 'utf-8' }),
name: 'myscript',
type: 'server_js'
}
]
})
}
}, function (err, file) {
// ...
});

Showing kartik growl via ajax in yii2

Am using kartik growl and i would like to show the growl via ajax success
I have tried
This is the javascript code:
$.post({
url: "forwardpr", // your controller action
dataType: 'json',
data: {keylist: keys,user:userdata},
success: function(data) {
console.log(data);
//$.pjax.reload({container:'#forward-grid'});
$.growl( data.growl );
},
error: function(err){
alert(err);
console.log("server error");
}
});
This is the controller code:
$growl = [
'title' => "Group members updated.<hr>",
'icon' => 'glyphicon glyphicon-ok-sign',
'message' => "Successifully updated.",
'showSeparator' => true,
];
echo json_encode(['response'=>"Successifully forwarded pr(s)", 'growl' => $growl ]);
If you see TypeError: $.growl is not a function, then it means you have not included required files to AppAsset.php file.
To solve this problem, go to assets/AppAsset.php file and add:
public $css = [
// ... Something else might be here
'css/jquery.growl.css',
];
And
public $js = [
// Something else might be here
'js/core.js',
];
Because of missing .js file, you have that error in console (TypeError: $.growl is not a function). But you also must add .css file as well because without it you will not see growl, even though it works.
I believe you're using the wrong function. Here's offical docs:
"Another important update is since version 3.x you no longer call the
plugin using $.growl(...) you must use $.notify(...)."
In another words, just try using $.notify(...) instead of $.growl(...).

Categories

Resources