Как получить JSON загрузки файла, используя обещание в функции onchange? - PullRequest
0 голосов
/ 27 апреля 2019

Я создаю веб, который конвертирует форму в json, но мне нужно конвертировать файл изображения, загрузить в base64 (строку) и добавить в json, но это только возврат URL, это успех в console.log (), но не в назначаемом значении this мой код

<form id="test" action="#" method="post">
    <div class="row">
        <div class="form-group">
            <label>First Name</label>
            <input name="namadepan" type="text" placeholder="Enter First Name Here.." class="form-control">
        </div>

    <div class="form-group">
        <label for="gambar">Foto</label>
        <input type="file"  class="form-control" name ="gambar" id="imagefile" value="Import"  onchange="toJSONString(document.getElementById('test'))" />
    </div>
    <p>
        <input type="submit" value="Send" class="btn btn-primary btn-block" />
    </p>
</form>

<textarea id="output"  class="form-control"></textarea>

это скрипт

function toJSONString(form) {
    var obj = {};
    var elements = form.querySelectorAll("input, select, textarea");
    for (var i = 0; i < elements.length; ++i) {
        var element = elements[i];
        var name = element.name;
        var value = element.value;

        if (element.type == "file") {
            var p = new Promise(function (resolve) {
                var reader = new FileReader();
                reader.onload = function () {
                    code = reader.result;
                    resolve(code);
                    console.log(reader.result);
                };
                reader.readAsDataURL(element.files[0]);
            });

            p.then(function (result) {
                value = result;
            })
        }

        if (name) {
            obj[name] = value;
        }
    }
    //return JSON.stringify( obj );
    document.getElementById("output").value = JSON.stringify(obj);
}

Результат выше

{"namadepan":"johndoe","gambar":"C:\\fakepath\\t2.jpg"}

что я ожидал

{"namadepan":"johndoe","gambar":"data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAUDBAQEAwUE"}

1 Ответ

0 голосов
/ 01 мая 2019

Значение C:\\fakepath\\t2.jpg взято из element.value.

Вы видите это, потому что вы сохранили значение до того, как обещание будет выполнено.

Чтобы правильно дождаться обещаниясм. ниже:

Обратите внимание, что toJSONString теперь является async функцией

async function toJSONString(form) {
    var obj = {};
    var elements = form.querySelectorAll("input, select, textarea");
    for (var i = 0; i < elements.length; ++i) {
        var element = elements[i];
        var name = element.name;

        // check `name`
        if(name) {
            // await the Promise here
            var value = await new Promise((resolve, reject) => {
                if (element.type == "file") {
                    var reader = new FileReader();

                    reader.onload = function () {
                        // resolve to data url
                        resolve(reader.result);
                    };
                    
                    reader.readAsDataURL(element.files[0]);
                } else {
                
                    // resolve to value
                    resolve(element.value);
                }
            });

            // store the value after the promise is resolved.
            obj[name] = value;
        }
        
    }
    //return JSON.stringify( obj );
    document.getElementById("output").value = JSON.stringify(obj);
}
<form id="test" action="#" method="post">
    <div class="row">
        <div class="form-group">
            <label>First Name</label>
            <input name="namadepan" type="text" placeholder="Enter First Name Here.." class="form-control">
        </div>

    <div class="form-group">
        <label for="gambar">Foto</label>
        <input type="file"  class="form-control" name ="gambar" id="imagefile" value="Import"  onchange="toJSONString(document.getElementById('test'))" />
    </div>
    <p>
        <input type="submit" value="Send" class="btn btn-primary btn-block" />
    </p>
</form>

<textarea id="output"  class="form-control"></textarea>
...