Dropzone.js and full path for each file - dropzone.js

I'm trying to recreate the folder structure of dropped files/folder with Dropzone.js.
Is there a way to have access to the full path of each file, so that the directory structure can be re-created on the php side?

This is a simple way you can send additionally full paths of all files which are in some folder(s):
dropzone.on("sending", function(file, xhr, data) {
// if file is actually a folder
if(file.fullPath){
data.append("fullPath", file.fullPath);
}
});

you can use a file reader for it, I did it in angular 5:
onFilesAdded(files: File[]) {
console.log(files);
this.dropzone.reset();
files.forEach(file => {
const reader = new FileReader();
let content;
reader.onload = (e: ProgressEvent) => {
content = (e.target as FileReader).result;
console.log(content);
};
this.previewImage(file).then(response => {
const imageItem = new FileItem(
response,
content,
);
let imagesComponentItems = this.store.value.imagesComponentItems;
imagesComponentItems = [...imagesComponentItems, imageItem];
this.store.set("imagesComponentItems", imagesComponentItems);
this.hasImages();
});
});
}

Related

Wait for promise to finish before continuing

I know many topics has been about promises and callback. I tried many ways but still, I don't succeed to solve it.
What I want is to edit a file locally, save it then upload it to S3. then another function is called to read from the file and display as a list
Unfortunately I am having error because the file is ending call another function to display to read then it is writing and saving in S3 as you can see in my [terminal ][1]
the file is properly edited and uploaded to s3
1- I tried as promises using then to excecute one after another
static async edit_product(req: any, res: any) {
console.log('edit_product param request',req.body)
try {
ExcelFile.EditFile(prod.product_code,prod.product_name).then(rs=> res.status(200).json({'success'}) ) ).catch((err) => {
console.error(err);
})
console.log('test')
}
2- using await and then
static async edit_product(req: any, res: any) {
console.log('edit_product param request',req.body)
try {
await ExcelFile.EditFile(prod.product_code,prod.product_name).then(rs=> rs)
console.log('test')
res.status(200).json({'success product edit':prod.product_code})
}
3-to upload file to S3
static async UploadFileS3() {
const file = config._path+config._foldername +config._filename
var s3 = new aws.S3({ accessKeyId: config._ACCESS_KEY_ID,secretAccessKey: config._SECRET_ACCESS_KEY });
var newversionId: string = ''
const params = {
Bucket: config._BUCKET_NAME,
Key: config._filename // File name you want to save as in S3
};
return s3.putObject(params, function(err, data) {
if (err) {console.log(err) }
newversionId = data.VersionId!
console.log("Successfully uploaded data ",newversionId);
});
};
4-edit file
const stream = new Stream.PassThrough();
var dataFile = wb.xlsx.readFile(file).then(rs=>{
var sh = rs.getWorksheet(config._sheetname);
for (let i = 2; i <= sh.rowCount; i++) {
let currRow = sh.getRow(i);
if (currRow.getCell(1).text==product_code){
currRow.getCell(2).value = product_name
currRow.commit();
break } }
console.log('edit ')
//save locally
wb.xlsx.writeFile(file).then(rs=>{console.log('edit filed successfully')});
const param = {Key: config._filename,
Bucket: config._BUCKET_NAME,
Body: stream,
ContentType: 'CONTENT_TYPE_EXCEL'
}
//save to s3
wb.xlsx.write(stream).then(() => {s3.upload(param, function (err,data) {
if (err) { console.log("Error", err); }
console.log("Upload Success", data.ETag);
ExcelFile.getAwsVersion().then(rs=>ExcelFile.saveFileBucketVersion(rs))
})
})
})
return dataFile //return promise
How can I make it to respect the step, edit first then return res.status(200).json({'success'}
[1]: https://i.stack.imgur.com/SsWhu.png
Your EditFile function seems to be not waiting for the end of the writeFile. The for loop starts the writeFile function but it is not awaited there. The possible solutions are
Move the write function out of the for loop. It looks weird anyway that you are potentially saving the changes multiple time.
If the write should be in the loop then use a promise compatible loop there (e.g. Bluebird.each)

Store and access data files in lambda function

How do I store custom file (.json in my case) in a lambda layer, so that I can access it like npm modules? I use node.js as a runtime. My current layer folder structure looks like this:
My modules stored in node_modules are visible and can be accessed as:
const { Client } = require('pg');
const knex = require('knex');
But when I try to list available files, I don't see my service-account-file.json file:
fs.readdir('./', (err, files) => {
files.forEach(file => {
console.log('#file')
console.log(file); // Returns only index.js
});
});
Here's what you need to use stored data files in Lambda function. Create a folder with name data_files, put your service-account-file.json file in there.
const path = require('path');
const fs = require("fs");
const loadDataFile = (file) => {
//create the filename including path
const fileName = `./data_files/${file}`;
//set up the variable
let resolved;
//if we have a lambda environment then add that to the path to resolve
if (process.env.LAMBDA_TASK_ROOT) {
//this creates an absolute path
resolved = path.resolve(process.env.LAMBDA_TASK_ROOT, fileName);
} else {
//otherwise resolve to the local path
resolved = path.resolve(__dirname, fileName);
}
try {
//get the text data as a string
let data = fs.readFileSync(resolved, 'utf8');
//convert to JS object
let parsedData = JSON.parse(data);
//TO DO - work data if required
//then return the data
return parsedData;
} catch (error) {
//if there'a an error in the data fetch then we need a report
console.log(error.message);
}
};
const data = loadDataFile('service-account-file.json');

How to take a photo and upload it to the server with Nativecript-camera

I am new to Nativescript Vue development, I am trying to take a photo and send it to the server. My code works fine on Android, but when I run on iOS, errors occur, the image doesn’t even paste onto the page and doesn’t upload to the server.
import * as camera from "nativescript-camera";
import * as bghttp from "nativescript-background-http";
const firebase = require("nativescript-plugin-firebase");
var session = bghttp.session("image-upload");
takePicture() {
camera.requestPermissions()
.then(() => {
camera.takePicture({ width: 300, height: 300, keepAspectRatio: true, saveToGallery:true })
.then(imageAsset => {
this.img = imageAsset.android;
})
.catch(e => {
console.log('error:', e);
});
})
.catch(e => {
console.log('Error requesting permission');
});
}
upload() {
var file = this.img;
var url = "https://bocorp.ru/assets/mobileNewOrder.php";
var name = file.substr(file.lastIndexOf("/") + 1);
// upload configuration
var bghttp = require("nativescript-background-http");
var session = bghttp.session("image-upload");
var request = {
url: url,
method: "POST",
headers: {
"Content-Type": "application/octet-stream",
"File-Name": name,
},
content: JSON.stringify({
Title: title
}),
description: "Uploading " + name
};
var task = session.uploadFile(file, request);
I understand that another code should be used in "this.img = imageAsset.android;" but I don’t understand how can I get a photo from the Iphone camera. I will be glad to any prompt
We save our images to the device, and then upload later as a multipart upload. You might be able to skip the file saving part, but it does allow us to keep from reading in the entire image for uploading later in our app flow (I guess if you already have the image source for display you could reuse it for upload on the same page).
Hope you find this helpful.
const imageSource = require('tns-core-modules/image-source')
// ...
camera.takePicture(cameraOpts)
.then(imageAsset => {
return imageSource.fromAsset(imageAsset)
})
.then(imageSource => {
let pathDest = '/path/on/device' // you define
console.log(`Created image source with width=${imageSource.width} height=${imageSource.height} at ${pathDest}`)
imageSource.saveToFile(pathDest, 'jpg', 50)
return pathDest // save this to look up later
})
Then when we need to upload
const mime = require('mime-types')
import * as bghttp from 'nativescript-background-http'
...
let session = bghttp.session('image-upload')
let request = {
url: 'https://yourendpoint.com/here',
method: 'POST',
androidAutoDeleteAfterUpload: true,
headers: {
'Content-Type': 'application/octet-stream',
}
}
// photoPath is known somehow. We use Vuex, but somehow it makes it to this page
let params = [
{ name: 'photo1', filename: photoPath, mimeType: mime.lookup(photoPath) }
]
return new Promise((resolve, reject) => {
let task = session.multipartUpload(params, request)
task.on('error', (e) => {
reject(e)
})
task.on('complete', res => {
resolve()
})
})

Attemp to invoke interface method java.lang.String com.facebook.react.bridge.ReadableMap etc on a null object reference

I'm getting this error after uploading image to firebase storage. I am using
"react-native": "0.55.4",
"react-native-fetch-blob": "^0.10.8",
"react-native-image-picker": "^0.26.10",
"firebase": "^5.0.4",
this is my code for uploading the image.
// Prepare Blob support
const Blob = RNFetchBlob.polyfill.Blob;
const fs = RNFetchBlob.fs;
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
window.Blob = Blob;
uploadImage = (uri, imageName, mime = "image/jpg") => {
return new Promise((resolve, reject) => {
const uploadUri =
Platform.OS === "ios" ? uri.replace("file://", "") : uri;
let uploadBlob = null;
const imageRef = db
.storage()
.ref("images/")
.child(imageName);
fs.readFile(uploadUri, "base64")
.then(data => {
return Blob.build(data, { type: `${mime};BASE64` });
})
.then(blob => {
uploadBlob = blob;
alert("blob is " + JSON.stringify(blob));
return imageRef.put(blob, { contentType: mime });
})
.then(() => {
uploadBlob.close();
return imageRef.getDownloadURL();
})
.then(url => {
resolve(url);
})
.catch(error => {
reject(error);
});
});};
Attempt to invoke interface method 'java.lang.String com.facebook.react.bridge.ReadableMap.getString(java.lang.String)' on a null object reference readAsText FileReaderModule.java:43 invoke Method.java invoke JavaMethodWrapper.java:372 invoke JavaModuleWrapper.java:160 run NativeRunnable.java handleCallback Handler.java:790 dispatchMessage Handler.java:99 dispatchMessage MessageQueueThreadHandler.java:29 loop Looper.java:164 run MessageQueueThreadImpl.java:192 run Thread.java:764
I faced the same error. The solution is to do a 'Fetch replacement' as the official documentation explains:
Since we are not implementing FileReader polyfill, you might run into
this error in some cases.
If you're facing this problem with Blob polyfill in Debug Mode, try
replace window.fetch with fetch replacement should fix it.
And:
If you have existing code that uses whatwg-fetch, now you don't have
to change existing code after 0.9.0, just use fetch replacement. The
difference between Official fetch and fetch replacement is that,
official fetch uses WHATWG-fetch js library which wraps XMLHttpRequest
polyfill under the hood, and our implementation simply wraps
RNFetchBlob.fetch.
Basically, you just have to add this to your code, just below your window.Blob = Blob; line:
const Fetch = RNFetchBlob.polyfill.Fetch
// replace built-in fetch
window.fetch = new Fetch({
// enable this option so that the response data conversion handled automatically
auto : true,
// when receiving response data, the module will match its Content-Type header
// with strings in this array. If it contains any one of string in this array,
// the response body will be considered as binary data and the data will be stored
// in file system instead of in memory.
// By default, it only store response data to file system when Content-Type
// contains string `application/octet`.
binaryContentTypes : [
'image/',
'video/',
'audio/',
'foo/',
]
}).build()
Documentation:
https://github.com/wkh237/react-native-fetch-blob/wiki/Trouble-Shooting#failed-to-execute-readastext-on-filereader
I am running into the same problem. It has something to do with the prep statements:
const Blob = RNFetchBlob.polyfill.Blob;
const fs = RNFetchBlob.fs;
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
window.Blob = Blob;
The error does not occur if I comment them out.
I have solved this by removing all this package because error still appearing even with fetch replacement I think Is triggered by
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
so I have used the old fashion
const uriToBlob = (uri) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function () {
resolve(xhr.response);
};
xhr.onerror = function () {
reject(new Error('uriToBlob failed'));
};
xhr.responseType = 'blob';
xhr.open('GET', uri, true);
xhr.send(null);
});
}

Form data is empty after using append?

I have a problem to append anything in form data. Its always empty. How can I append image file and some other data?
var data = new FormData();
fileResult = this.$els.fileIntroImage.files;
data.append('name',this.property_credentials.name);
data.append('default_image',this.$els.fileIntroImage.files[0],File);
console.log('data',data);
Took me a while to get my head around file uploads with Vue.
Here is the methods object on my Vue component:
methods: {
upload(e) {
e.preventDefault();
var self = this;
var formData = this.gatherFormData();
this.$http.post('/path/to/upload/method', formData)
.then(response => {
//do stuff
},
(response) => {
//show error
});
},
gatherFormData() {
const data = new FormData();
data.append('image', this.$refs.image.files[0]);
data.append('other_field', this.other_field);
return data;
}
},
This should then function as as a normal file field as far as Laravel is concerned.
It can be logged, you just need to log each item. You can use FormData’s iterator function to do so.
var data = new FormData();
data.append('name',this.property_credentials.name);
data.append('default_image',this.$els.fileIntroImage.files[0],File);
data.forEach(el => console.log(el));

Resources