skip to Main Content

I can’t figure out why only one item is getting passed to the controller. Everything works as expected except if multiple files are selected it only takes the first file.

$("#photoSubmit").click(function () {
    var formData = new FormData();
    var imageDescriptions = [];

    // Collect all descriptions
    $("#image-list .list-images .list-itm").each(function () {
        var description = $(this).find("textarea").val();
        imageDescriptions.push(description);
    });

    // Iterate through file inputs and match each file with the respective description
    $("#frmUpload input[type='file']").each(function (index) {
        var fileInput = this;
        var description = imageDescriptions[index] || ""; 

        if (fileInput.files.length > 0) {
            formData.append("Photos[" + index + "].Image", fileInput.files[0]);
            formData.append("Photos[" + index + "].Description", description);
            formData.append("Photos[" + index + "].UserId", $("#u-id").val());
        }
    });

    formData.forEach(function (value, key) {
        console.log(key, value);
    });

    $.ajax({
        async: true,
        type: 'post',
        data: formData,

        contentType: false,
        processData: false,
        dataType: "html",
        url: "/User/Photo/AddPhoto",
        success: function (partialView) {
            // Handle the response here
        },
        error: function (partialView) {
            // Handle errors here
        }
    });
});

”’

2

Answers


  1. In your code you have fileInput.files[0] which only takes the first file from the file input. you could try below code which will help you to send multiple file:

    $("#frmUpload input[type='file']").each(function (index) {
        var fileInput = this;
        var description = imageDescriptions[index] || ""; 
    
        // Loop through all selected files, not just the first one
        for (var i = 0; i < fileInput.files.length; i++) {
            formData.append("Photos[" + index + "].Image", fileInput.files[i]);
            formData.append("Photos[" + index + "].Description", description);
            formData.append("Photos[" + index + "].UserId", $("#u-id").val());
        }
    });
    

    Also, there’s an issue with your debug logging; formData.forEach is not a valid method as FormData does not have a forEach method. If you want to see the contents of the formData, you can iterate through it using for...of:

    for (let [key, value] of formData.entries()) {
        console.log(key, value);
    }
    

    Make sure each file should have a unique key in the formData if they are to be identified separately on the server-side.check your backend is also correctly set up to handle multiple files being uploaded with the same key pattern (Photos[index].Image, Photos[index].Description). It should be able to differentiate between different files and their descriptions based on the index.

    Login or Signup to reply.
  2. fileInput.files[0] will always give you the first uploaded file data.

    So you need to change:

    fileInput.files[0]
    

    To

    fileInput.files[index]
    

    Also, you can change your code like below: (because array notation itself takes care of indexing from 0,1,2.. so no need to use index there)

    if (fileInput.files.length > 0) {
        formData.append("Photos[].Image", fileInput.files[index]);
        formData.append("Photos[].Description", description);
        formData.append("Photos[].UserId", $("#u-id").val());
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search