How to find out when files traverse is over? - javascript

I want to create my own drag and drop component and i use this:
Does HTML5 allow drag-drop upload of folders or a folder tree?
everything works fine, but i want to find out when files traverse is over, because i want to create an array of string, which contains file names and then do sth.
traverseFileTree function contains callbacks so there are async tasks. I need to wait until callbacks are done and i don't know how to do it. I would use jQuery.Deffered but traverseFileTree is called from a loop and -in addition- this is a recursive function.
this.dndElement.addEventListener('drop', (ev: any) => {
var items = ev.dataTransfer.items;
for (var i = 0; i < items.length; i++) {
this.traverseFileTree(items[i].webkitGetAsEntry());
}
// i want to wait until callbacks in the traverseFileTree are done and do sth with fileNames array
});
public traverseFileTree(item, path?) {
path = path || "";
if (item.isFile) {
item.file((file) => {
this.fileNames.push(file.name);
});
} else if (item.isDirectory) {
var dirReader = item.createReader();
dirReader.readEntries((entries) => {
for (var j = 0; j < entries.length; ++j) {
this.traverseFileTree(entries[j], path + item.name + "/");
}
});
}
}
UPDATE:
I did sth like this:
this.dndElement.addEventListener('drop', (ev: any) => {
var items = ev.dataTransfer.items;
for (var i = 0; i < items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
this.traverseFileTree(item);
}
}
Promise.all(this.promises).then(() => { console.log(this.fileNames); });
});
public traverseFileTree(item, path?) {
path = path || "";
console.log(item);
if (item.isFile) {
this.fileNames.push(item.fullPath);
} else if (item.isDirectory) {
this.promises.push(new Promise((resolve, rejected) => {
var dirReader = item.createReader();
dirReader.readEntries((entries) => {
for (var j = 0; j < entries.length; ++j) {
this.traverseFileTree(entries[j], path + item.name + "/");
}
resolve();
})
}));
}
}
and now i get list of files ... but only from "first level".
Adir
Bdir
1File
2File
Cdir
3File
4File
5File
6File
And i get 1File,2File,5File,6File but 3File,4File don't. Why?

You kick off here :
this.traverseFileTree(items[i].webkitGetAsEntry());
And then the function public traverseFileTree(item, path?) { takes over. The function is sync (even though its recursive). Once it returns you should already be in good shape 🌹
However please note that this is webkit only :https://developer.mozilla.org/en/docs/Web/API/DirectoryReader#readEntries and is likely to be removed at some point.

Related

Cypress - Create a new 'it' on each loop cycle

I'm automating the completion of a questionnaire via Cypress using fixtures. I need to create a new IT statement on each iteration of a loop running as currently if 1 set fails in the loop, then the rest of the dataset does not run.
Any help would be appreciated.
context('Questionnaire Completion', () => {
Cypress.Cookies.debug(true);
beforeEach(function() {
cy.fixture('data_set_4').then((testdata) => {
this.data = testdata
});
});
describe ('I will complete the form with each entry in the data set', function() {
it ('I will complete the form with each entry in the data set', function() {
for (let i = 0; i < this.data.testdata.length ; i++) {
participantcreation(this.data.testdata[i].DataEntry);
//I will enter a name and click Next
Name(this.data.testdata[i].DataEntry);
for (let j = 1; j < 31 ; j++) {
let answer = this.data.testdata[i]['Q' + j] - 1;
cy.get('#questionnaire_question_'+j+'_'+answer).click({ force: true });
}
});
});
});
Not entirely sure about what is being asked here but if you wish to create multiple 'its' depending on what you need you can just put it in a loop
describe('Tests', () => {
var i;
for (i = 0; i < 5; i++) {
it(`Test ${i}`, () => {
cy.wait(200)
});
}
});

Matching strings don't trigger condition in Javascript

I am trying to do a very simple stock counting app, and display dynamically the stocks for each item. When I try to pair the button with its item, it doesn't work, even though the 2 strings are actually a match.
Here is the faulty function:
socket.on('Stock init', (data) => {
items = data.items;
displayStock(items);
});
function displayStock(items) {
fridgeItem.forEach((fridgeItem) => {
for (let i = 0; i < items.length; i++) {
var databaseProduct = items[i].name;
var databaseQuantity = items[i].chilled.toString();
console.log(fridgeItem.textContent, databaseProduct);
}
if (fridgeItem.textContent === databaseProduct) {
fridgeItem.textContent = databaseProduct + ' ' + databaseQuantity;
} else {
console.log('err');
}
});
}
Answer might be stupid but I can't see it at the moment. Thanks

Javascript Recursion returning undefined

I'm struggling in a recursive Javascript function to find a specific subdirectory. This is my code:
function navigateToParent() {
var parentFullPath = parentDirectory(); // gets the full Path String
if (parentFullPath != null) {
var parent = getDirectoryByName(parentFullPath, rootDirectory);
// set the parent directory object as the current one
currentDirectory(parent);
}
}
function getDirectoryByName(fullName, myDirectory) {
if (myDirectory.fullName == fullName) {
return myDirectory;
} else {
var subs = myDirectory.subDirectories;
for (i = 0; i < subs.length; i++) {
return getDirectoryByName(fullName,subs[i]);
}
}
}
Every directory object has the properties fullName(string),subDirectories(array of directories) and files(array of files). My aim is to get the correct directory object, where it's fullName is matching.
I know, that i have to break the for loop in some way, but i don't know how to do it exactly.
After overthinking the logic i came to this solution (seems to work):
function getDirectoryByName(fullName, myDirectory) {
if (myDirectory.fullName == fullName) {
return myDirectory;
} else {
var subs = myDirectory.subDirectories;
for (i = 0; i < subs.length; i++) {
var match = getDirectoryByName(fullName, subs[i]);
if (typeof match !== "undefined"){
return match;
}
}
}
}

Search through JSON to find sepcific values

I am trying to search a JSON from client to get specific value , linear search is working if i go with specific keys but when i search from a key in middle of json it returns nothing.
Here is what i am trying
$.each(jsonStr, function (i, v) {
var folderID = '1408614499420';
if (v['#id'] == folderID) {
alert(v.folder.file['#id']);
}
});
I want to search a specific folder by its id and get all files in that specific folder.
Here is the Fiddle with actual json.
do u want something like this
$("#menuArea li").live('click', function (event) {
$.each(jsonStr.hierarchy.folder["folder"], function (i, v) {
var folderID ='1408614499420';//any id of folder
if (v['#id'] == folderID) {
alert(v.file['#id']);//file where folder id is folderID
}
});
event.stopPropagation();
});
Here's working fiddle
http://jsfiddle.net/9kw99L2h/6/
Edit :-
Code for getting all subfolders & files
function getAllSubFolders(folder) {
var subFolders = [];
if (folder.folder) {
if (folder.folder instanceof Array) {
for (var i = 0; i < folder.folder.length; i++) {
subFolders[subFolders.length] = folder.folder[i]['#id'];
subFolders = subFolders.concat(getAllSubFolders(folder.folder[i]))
}
} else {
subFolders[subFolders.length] = folder.folder['#id'];
subFolders = subFolders.concat(getAllSubFolders(folder.folder))
}
}
return subFolders;
}
function getAllFiles(folder) {
var files = [];
if (folder.file) {
if (folder.file instanceof Array) {
for (var i = 0; i < folder.file.length; i++) {
files[files.length] = folder.file[i]['#id'];
}
} else {
files[files.length] = folder.file['#id'];
}
}
if (folder.folder) {
files = files.concat(getAllFiles(folder.folder));
}
return files;
}
Fiddle http://jsfiddle.net/9kw99L2h/9/

Save values into an array from a function which is called consecutively

I have a function which is called when a file is needed to be read in a folder. In this case since i have 3 files in that folder, it is called 3 times consecutively. I need to save all files info into array mapped_data2 like that:
mapped_data2[0] = inner_data1 //first file info,
mapped_data2[1] = inner_data2 //second file info etc.
However using my code i am having just the first files information 3 times. I am a bit confused with global variables, if you can point out the problem, i would appreciate it.
here is the code:
var mapped_data = [];
var mapped_data2 = [];
function o(msg) {
if (msg.data) {
var inner_data = [];
var lines = msg.data.split('\n'); //read lines of a file
for (var i = 2; i < lines.length; i++) {
if (lines[i].length > 0) {
.. //do same data format here
inner_data.push([son, vactual, voutput]);
}
}
mapped_data = inner_data;
}
else {
if (msg.topic == "/somefolder/somefolder") {
for (var i = 0; i < msg.args.length; i++) {
var filename = msg.args[i];
aw.get(filename);
}
}
}
}
function de() { //where i wanted to use these files info
for (var i = 0; i < 3; i++) {
mapped_data2[i] = { key: "Group" + (i + 1), values: mapped_data };
}
var datam = mapped_data2;
var den = JSON.stringify(datam);
document.write(den);
};
function init() {
..//create new client called aw for the server application and start it;
..//if the connection is established:
aw.onmessage = o;
aw.get("/somefolder/somefolder"); // request list of files in a folder
};
//when html page is being onload, call the functions init() and de()
var mapped_data2 = [];
function o(msg) {
var mapped_data = []; // this doesn't need to be global
if (msg.data) {
var inner_data = [];
...
mapped_data = inner_data;
} else {
...
}
mapped_data2.push({ key: "Group" + mapped_data2.length + 1, values: mapped_data };)
// do more stuff as in den()
}

Categories

Resources