5

Im creating an invoice for books, and aim to submit it via ajax. Im trying to json encode the array of books in the invoice, however I keep getting a blank value

 //create item list
    var order_items = [];
    $('#mi_books tbody tr.userbooks').each(function(index)
    {
        var bookisbn = $(this).find('td .mi_isbn').text();

        var bookdata = [];
        bookdata['isbn'] = bookisbn;
        bookdata['title'] = $(this).find('.mi_title').text();
        bookdata['qty'] = $(this).find('.mi_qty').text();
        bookdata['price'] = $(this).find('.mi_price').text();

        order_items.push(bookdata);

    });
    alert(JSON.stringify(order_items));
    alert(order_items.toString());
    console.log(order_items);

alert(JSON.stringify(order_items));
Outputs: [[]]

alert(order_items.toString());
Outputs: blank

console.log(order_items);
Output:

Array[1]
0: Array[0]
isbn: "9781401216672"
length: 0
price: "1007"
qty: "1"
title: "Batman: The Killing Joke"
__proto__: Array[0]
length: 1
__proto__: Array[0]

My array is being created, but somehow I cant seem to json encode it? Am I doing something wrong?

Antony
  • 14,900
  • 10
  • 46
  • 74
pinkpixycoder
  • 91
  • 2
  • 6

3 Answers3

4

Array and Object are different beasts. Your bookdata is not an array, but an object, thus, you should create it with

var bookdata = {};

  • And, for readability, assign with `bookdata.isbn = ...` instead of square brackets and strings (it is the same, by definition, in ES5 spec). –  Jul 10 '13 at 14:18
  • See also @Jack's answer below, you could bind creation of empty `{}` with filling it as shown there (I would probably do it, too, as a second step; I fixed the immediate bug). –  Jul 10 '13 at 14:23
  • Thanks for explaining it, I assumed bookdata was also an array because the console.log output said 'array' – pinkpixycoder Jul 10 '13 at 17:08
  • @pinkpixycoder Yes, it was an array, you created it as such: `[]`. The variable will hold what you put to it, empty array `[]`, empty object `{}` or whatever else. –  Jul 10 '13 at 17:11
3

Arrays are serialized differently with JSON.stringify() as opposed to regular objects (only properties of UInt32 are serialized). Since you're only adding textual properties to the bookdata, you should use anonymous objects like this:

var bookdata = {
    isbn: bookisbn,
    title: $(this).find('.mi_title').text(),
    qty: $(this).find('.mi_qty').text(),
    price: $(this).find('.mi_price').text()
};
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
0

you may try

var order_items = {};
$('#mi_books tbody tr.userbooks').each(function(index)
{
    var bookisbn = $(this).find('td .mi_isbn').text();

    var bookdata = {
      'isbn': bookisbn,
      'title': $(this).find('.mi_title').text(),
      'qty': $(this).find('.mi_qty').text(),
      'price': $(this).find('.mi_price').text()
    };
    order_items[index] = bookdata;
});
alert(JSON.stringify(order_items));

your only mistake was a try to create associative arrays instead of using objects, that can do it

vladkras
  • 16,483
  • 4
  • 45
  • 55