T
T
Tyler Lowell2020-01-14 14:40:33
JavaScript
Tyler Lowell, 2020-01-14 14:40:33

Why is JSON.stringify losing part of the object?

Good afternoon! I have a javascript object

let form = {
  img: "...", // тут закодированная base64 строка
  name: "smth",
  desc: "smth"
}

When trying to turn an object into a string for transmission, a problem arises: the output is the following string: That is, the base64 image was lost somewhere. Can this be fixed somehow?
{"name":"smth","desc":"smth"}
5e1da89c514b3389809105.png
All code

document.getElementById("back").addEventListener("click", function(e){
  move("search")
})

document.getElementById('ok').addEventListener('click', () => {
  let form = {};
  if(document.getElementById('load_img').files.length > 0) {
    var img = document.getElementById('load_img').files[0];
    var reader = new FileReader();
    reader.readAsDataURL(img);
    reader.onload = function() {
      form.img = encodeURIComponent((reader.result).split(',')[1]);
      // form.img = encodeURIComponent(btoa('hahahahahahh'));
    }
  } else {
    form.img = '';
  }

  form.name = encodeURIComponent(document.getElementById('name').value);
  form.desc = encodeURIComponent(document.getElementById('desc').value);

  console.log(form);

  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://host/api/?product.create=' + JSON.stringify(form));
  // xhr.send();

  console.log('Form: ' + form);
  console.log(JSON.stringify(form));

  xhr.onreadystatechange = () => {
    if(xhr.readyState == 4 && xhr.status == 200) {
      console.log(xhr.responseText);
      var data = JSON.parse(xhr.responseText);

      if(data.code == 1) {
        alert('Товар успешно создан');
        move('search');
      } else {
        alert('Ошибка! ' + data.text);
        move('search');
      }
    }
  }
});

Answer the question

In order to leave comments, you need to log in

3 answer(s)
T
Tyler Lowell, 2020-01-14
@tdesu

Solved the problem;)
The problem was that the file reader works in asynchrony, as Aleksey Ten said .
Thank you all for your help!
Placed XHR send in a separate function and only call when "onload" is triggered on the file reader.

let form = {};
document.getElementById('ok').addEventListener('click', () => {
  if(document.getElementById('load_img').files.length > 0) {
    var img = document.getElementById('load_img').files[0];
    var reader = new FileReader();
    reader.readAsDataURL(img);
    reader.onload = function() {
      form.img = encodeURIComponent((reader.result).split(',')[1]);
      form.name = encodeURIComponent(document.getElementById('name').value);
      form.desc = encodeURIComponent(document.getElementById('desc').value);
      send();
    }
  } else {
    form.img = '';
    form.name = encodeURIComponent(document.getElementById('name').value);
    form.desc = encodeURIComponent(document.getElementById('desc').value);
    send();
  }

  console.log(form);
});

function send() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'https://host/api/?product.create=' + JSON.stringify(form));
  // xhr.send();

  console.log('Form: ' + form);
  console.log(JSON.stringify(form));

  xhr.onreadystatechange = () => {
    if(xhr.readyState == 4 && xhr.status == 200) {
      console.log(xhr.responseText);
      var data = JSON.parse(xhr.responseText);

      if(data.code == 1) {
        alert('Товар успешно создан');
        move('search');
      } else {
        alert('Ошибка! ' + data.text);
        move('search');
      }
    }
  }
}

A
akhoronko, 2020-01-14
@akhoronko

form.img is populated asynchronously in reader.onload, so it might not be there when JSON.stringify is called

E
Eugene Chefranov, 2020-01-14
@Chefranov

When generating a base64 image, you probably have line feeds or something like that. The code should work

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question