2017-10-19 15 views
1

Je suis en train de publier un tableau javascript d'un objet dans un appel ajax mais j'ai la valeur de chaîne "[]". Quand j'essaye de consoler.log la longueur de tableau indique zéro.Impossible de publier le tableau javascript de l'objet

Voici le code que je utilise

var masterFileArray = []; // where I will store the contents 
function readMultipleFiles(evt) { 
//Retrieve all the files from the FileList object 
var files = evt.target.files; 
if (files) { 
    for (var i = 0, f; f = files[i]; i++) { 
     var r = new FileReader(); 
     r.onload = (function (f) { 
      return function (e) { 
       var contents = e.target.result; 
       masterFileArray.push({name:f.name, contents: contents, type:f.type, size:f.size}); // storing as object 

      }; 
     })(f); 
     r.readAsText(f); 
    } 
    console.log(masterFileArray); 
    new Ajax.Request('fileupload.php', { 
    method: 'post', 
    parameters: {files: JSON.stringify(masterFileArray)}, 
    onSuccess: function(transport){ 
     var response = transport.responseText; 
     console.log(response); 
    } 
}); 

} else { 
    alert('Failed to load files'); 
    } 
} 
document.getElementById('upfiles').addEventListener('change', readMultipleFiles, false); 

est comment il ressemble à une inspection

enter image description here

Qu'est-ce que je fais mal? Toute aide serait appréciée, merci.

+2

Parce que vous ajoutez les éléments de manière asynchrone dans la fonction 'onload', essentiellement. 'readAsText' ne bloque pas et n'attend pas que le fichier soit lu, ainsi votre code procède immédiatement à faire la demande avant que le tableau soit peuplé. –

+0

Vous effectuez la requête Ajax AVANT que vos fichiers aient été lus par le lecteur de fichiers. – Danmoreng

+1

R.onload est-il déclenché? Console.log à l'intérieur pour savoir que :) –

Répondre

1

Vous pouvez poster après lecture terminé, Ici a introduit left_loaded_count pour obtenir l'état de la lecture. Essayez comme ceci.

var masterFileArray = []; // where I will store the contents 
var left_loaded_count = 0; 
function readMultipleFiles(evt) { 
//Retrieve all the files from the FileList object 
var files = evt.target.files; 
if (files) { 
    for (var i = 0, f; f = files[i]; i++) { 
     var r = new FileReader(); 
     r.onload = (function (f) { 
      return function (e) { 
       var contents = e.target.result; 
       masterFileArray.push({name:f.name, contents: contents, type:f.type, size:f.size}); // storing as object 
       left_loaded_count -= 1; 
       if(left_loaded_count == 0) 
       { 
       console.log(masterFileArray); 
       new Ajax.Request('fileupload.php', { 
        method: 'post', 
        parameters: {files: JSON.stringify(masterFileArray)}, 
        onSuccess: function(transport){ 
        var response = transport.responseText; 
        console.log(response); 
        } 
        }); 
       } 
      }; 
     })(f); 
     left_loaded_count += 1; 
     r.readAsText(f); 
    }  
} else { 
    alert('Failed to load files'); 
    } 
} 
document.getElementById('upfiles').addEventListener('change', readMultipleFiles, false); 
1

readAsText() est une opération asynchrone, mais procéder à l'appel AJAX tout de suite au lieu d'attendre les opérations de lecture à la fin. C'est pourquoi votre console.log(masterFileArray) imprime un tableau vide, quand il s'exécute, aucune des opérations n'est terminée et le tableau est toujours vide. La meilleure façon de résoudre ceci est d'emballer chaque opération de lecture de fichier dans une promesse, puis de poursuivre l'appel AJAX une fois que toutes ces promesses auront été résolues.
Débarrassez-vous de var masterFileArray = [] et changer votre code dans le bloc if (files) { ... } à ceci:

Promise.all(files.map(function(f) { 
    return new Promise(function(resolve) { 
     var r = new FileReader(); 
     r.onload = function (e) { 
     var contents = e.target.result; 
     resolve({name:f.name, contents: contents, type:f.type, size:f.size}); // resolve promise with object 
     }; 
     r.readAsText(f); 
    }); 
    })).then(function(masterFileArray) { 
    // All promises have resolved and their results have been collected in masterFileArray 
    console.log(masterFileArray); 
    new Ajax.Request('fileupload.php', { 
     method: 'post', 
     parameters: {files: JSON.stringify(masterFileArray)}, 
     onSuccess: function(transport){ 
     var response = transport.responseText; 
     console.log(response); 
     } 
    ); 
    });