Is it possible to combine two FileList objects? - javascript

I have a FileList object which holds previously uploaded documents. I'm trying to use another function to add more files to this collection, by using another FileList object, so I need to "append" the secondary FileList object onto the primary one. How would it be possible to achieve this?

You have to first convert the FileList objects to Arrays, after which you can simply concat the multiple arrays.
const joined = Array.from(fileListA).concat(Array.from(fileListB));

const filesArray = [...filesList1, ...filesList2];
console.log(filesArray) // [File, File, File, File, File, ...]

The selected answer clarifies the path completely. A temp variable can also be used here, like the following:
var temp = files
files=Array.prototype.slice.call(temp).concat(Array.prototype.slice.call(event.target.files))
Also in React for setting the files in the state the following code can be used inside handleInputChange function:
var temp = this.state.files;
this.setState({
files: Array.prototype.slice.call(temp).concat(Array.prototype.slice.call(event.target.files))
})

var fileLists = [fileListA, fileListB];
var files = fileLists.reduce(function(a, c) {
return Array.prototype.concat.call(Object.values(a), Object.values(c))
})

Related

Read from 2 Different file to be 2 dimensional array Javascript

How to read two .txt files and turn these 2 files to a 2d array?
I already have a code like this :
var fs = require('fs')
file = './text1.txt'
fs.readFile(file,'utf-8', (e,d) => {
textByLine = d.split('\r\n');
console.log("test : " + textByLine[1])
})
source
I succeeded to store the file in a 1d array but now I have 2 files and I want to store them in a 2d array.
How to do this?
Thank you
You can have a variable at top with an empty array, after you read the files and push that result to that variable , like this:
const 2dArray = [];
const fillArray = (path)=> {
fs.readFile(path,'utf-8', (e,d) => {
2dArray.push(d.split('\r\n')) // the result is already an array.
});
});
after that you can call each file like this :
// read the files and push the result to the variable 2dArray
fillArray('./text1.txt');
fillArray('./text2.txt');
//you can read the 1st result of your 1st file array like this
const firstPartOfArray = 2dArray[0][0]; // text1 first result value
if you don't need to have the result files in order i strongly recommend to use async function.
also you can use thinks like fs-jetpack package to handle this, or glob

How do I add a header row to a CSV file using node-csv?

I am parsing a bunch of csv files with node using node-csv. I have hundreds of files that need to be parsed, however, I need to add a header row to each file to make use of the 'columns' option in the parser. The columns option parses each row as an object with the header row serving as object keys, however for this option to work, you of course need a header row.
By looking at the docs, my gut tells me I should be able to pipe my node stream through a transform function that adds the row, but I'm having a difficult time making this work without altering the existing data in the file.
Here is what I'm thinking, but how do I write a row to the 'zero' column?
let createStream = function() {
let stream = fs.createReadStream(transPath+'/'+file, {encoding: 'utf8'});
let parser = csv.parse({columns: true});
let transform = csv.transform(function(record, doneTransform){
//check if first zero row,
//Add header column.
doneTransform();
});
return stream.pipe(transform).pipe(parser);
};
createStream().on('data', function(transaction){
//do stuff with object data
});
The real solution:
let createStream = function() {
let stream = fs.createReadStream(transPath+'/'+file, {encoding: 'utf8'});
let parser = csv.parse({skip_empty_lines: false, auto_parse: true, columns: header});
return stream.pipe(parser);
};
createStream().on('data', function(transaction){
q.push(transaction);
});
I solved this problem by looking at the issue a little differently. Let me explain.
First, My initial attempt above didn't work because it used the Transform and Parse packages incorrectly. You can use them independently, as the package suggests, but if you do decide to use them together, the proper usage requires that you parse your CSV first, and then transform it...Thus, my attempt above is a dead on arrival.
Secondly, once I backed away from my requirement to use headers, I realized that what I really wanted was an object with the correct key/value pairs, which led me to trying to transform the data on my own, instead of relying upon the 'columns' option to do this for me.
This led to my result: If i can guarantee the order, and number of columns for each record, then can build an object from two arrays with the corresponding data in a transform function.
Here is the code:
let createStream = function() {
let stream = fs.createReadStream(transPath+'/'+file, {encoding: 'utf8'});
let parser = csv.parse({skip_empty_lines: false, auto_parse: true});
let transform = csv.transform(function(record, doneTransform){
let newObject = _.zipObject(header, record);
doneTransform(null, newObject);
});
return stream.pipe(parser).pipe(transform);
};
createStream().on('data', function(transaction){
q.push(transaction);
});
'header' is an array of keys I wish to pair up with a corresponding value that I parse from the CSV.
I am making use of lodash's zipObject function that creates an Object from two arrays. You can find that here: zipObject.
Hope this helps someone find their solution when they don't have headers on their CSV files.

Return complete file name if only know a prefix (substring)

Using JavaScript / jQuery, how can I get the complete file name of a file, when I only know its prefix?
For example:
The folder I'm browsing contains pic files:
001_PicA.jpg
002_PicB.jpg
004_PicC.jpg
007_PicD.jpg
008_PicE.jpg
Now let's say in my script I only have __002__ as information available. How could I get the complete file name (that is: 002_PicB.jpg)?
As other said, it is not possible to invoke directly. However if the list of files are available as an array then try the below approach.
Iterate each item in the array and then check for it occurance using idexOf().
var fileName = ["001_PicA.jpg", "002_PicB.jpg", "003_PicC.jpg"];
var contains = [];
$.each(fileName, function (i, j) {
if (j.indexOf("002") != -1) {
contains.push(j); //push the items to the array
}
});
console.log(contains); //returns 002_PicB.jpg
JSFiddle

How can i read an object filelist array in javascript?

I have created an array to store a list of selected files. Well, I have to be honest, I looked up the code and when I realized it worked for my purpose, I used it. Now I need to access this array in order to delete some files manually, but I have tried using the index of each sector, but this does not work.
This is how i create the array and store files.
var files = [];
$("button:first").on("click", function(e) {
$("<input>").prop({
"type": "file",
"multiple": true
}).on("change", function(e) {
files.push(this.files);
}).trigger("click");
});
How could I read the array files[] if it contains an object fileList or obtain indexs from the array?
Here's how I understand your code:
Each time the first button in the dom is clicked a file input dialogue which accepts multiple files is generated. Upon return the dialogue emits a change event with a files variable (a FileList object) attached to the function context (this). Your code pushes the newly created FileList onto the files array. Since the input accepts multiple files each object pushed onto the files array is a FileList object.
So if you want to iterate through all elements in the files array you can put a function in the change event handler:
var files = [];
$("button:first").on("click", function(e) {
$("<input>").prop({
"type": "file",
"multiple": true
}).on("change", function(e) {
files.push(this.files);
iterateFiles(files);
}).trigger("click");
});
function iterateFiles(filesArray)
{
for(var i=0; i<filesArray.length; i++){
for(var j=0; j<filesArray[i].length; j++){
console.log(filesArray[i][j].name);
// alternatively: console.log(filesArray[i].item(j).name);
}
}
}
In the iterateFiles() function I wrote filesArray[i][j] isn't really a multidimensional array -- but rather a single dimensional array containing FileList objects which behave very much like arrays...except that you can't delete/splice items out of them -- they are read-only.
For more info on why you can't delete see: How do I remove a file from the FileList
Since you are using jQuery you can use $.grep
files=$.grep( files, function(elementOfArray, indexInArray){
/* evaluate by index*/
return indexInArray != someValue;
/* OR evaluate by element*/
return elementOfArray != someOtherValue;
});
API Reference: http://api.jquery.com/jQuery.grep/
Something like this?
for(var i = 0; i < files.length; i++) {
alert(files[i][0].name);
if (files[i][0].name == 'file.jpg') {
files.splice(i, 1) //remove the item
}
}
That is, there is always one file in each FileList due to the way you select it. So for each filelist you are only interested in the first file in it. For each file you can just get the properties as defined here: http://help.dottoro.com/ljbnqsqf.php

Javascript Objects in Arrays

I'm trying to use the Ajax File Upload as featured here: http://valums.com/ajax-upload/
As you can see, I need to create a qq.FileUploader object to initialize the script. However, I need to be able to dynamically create this objects without knowing the IDs of the elements. I've tried creating something like this:
var uploader, i = 0;
$(".file-upload").each(function() {
$e = $(this);
i++;
uploader[i] = new qq.FileUploader({
element: $(this)[0],
action: 'uploadfile.php',
allowedExtensions: ['doc', 'docx', 'pdf'],
multiple: false,
onComplete: function(id, fileName, responseJSON) {
$($e).siblings('input').val(responseJSON.newfilename);
}
});
});
I've learned that the [i] part I have added breaks the script, because I cannot have objects inside of an array.
Is there another way I can create this objects dynamically? They need to all have a unique name, otherwise the onComplete function gets overwritten for all of them. I experimented with using eval(), but I can't seem to make it work correctly.
You have to declare uploader as an array first :
var uploader = [];
Because you declared the variable without defining it, it has the default value of undefined , and your code was translated into something like undefined[i] which triggers an error.
Has to be something like
var uploader = {};
or else uploader is null and you cannot assign anything to it.
EDIT:
So there're two opitions, in my opinion, if one wants to have an array than it makes sense to declare one, var uploader = []; and then use the uploader.push() method or define it as an object var uploader = {}; and just do uploader[i] = ....
It is also possible to do the latter with an a array, but in the latter case I see no point in maintaining the counter (i).

Categories