Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Serializing an Array of Objects #69

Closed
StephenEsser opened this issue Jan 3, 2017 · 7 comments
Closed

Serializing an Array of Objects #69

StephenEsser opened this issue Jan 3, 2017 · 7 comments

Comments

@StephenEsser
Copy link

I have an input field consisting of an array with nested values.

<input name="array[0][value]" type="text" value="Label 1">

I am currently using the following solution found on StackOverflow: http://stackoverflow.com/questions/1184624/convert-form-data-to-javascript-object-with-jquery/8407771#8407771

Which serializes this structure into:

array: [ { value: 'Label 1' } ]

However, when using this library it serializes down to:

array: { '0': { value: 'Label1' } }

Is there a way to do the same thing using marioizquierdo/jquery.serializeJSON?

I need to be able to serialize multiple levels of Arrays / Objects. A possible structure being:

array: [ { array: [ 'val' ], value: 'text' } ]

Let me know if this is possible, I've attempted to use useIntKeysAsArrayIndex but this doesn't seem to work with nested objects, only single level key / value.

@marioizquierdo
Copy link
Owner

Yes of course, just use the option useIntKeysAsArrayIndex: true, for example:

$('input').serializeJSON({useIntKeysAsArrayIndex: true});

Which instructs the serializer to assume numeric keys are array indexes.

@marioizquierdo
Copy link
Owner

marioizquierdo commented Jan 4, 2017

Oh wait, I didn't see your last line. Seems like you already used the useIntKeysAsArrayIndex option and didn't work. Can you be more specific about what is not working? Please show the HTML and the serialization that didn't work as expected.

Your example:

<input name="array[0][value]" type="text" value="Label 1">

Should serialize like this:

$('input').serializeJSON({useIntKeysAsArrayIndex: true});
// =>
{"array": [{"value": "Label 1"}]}

@marioizquierdo marioizquierdo reopened this Jan 4, 2017
@StephenEsser
Copy link
Author

Thank you for such a fast reply, that's awesome. I've simplified the code down to a single input. This is what I have.

<form id="form-id">
  <input name="array[0][value]" value="value">
</form>

My testing function which I override submit: ( I am serializing the form, do I need to serialize inputs individually?)

  function testFormSubmit(event) {
    event.preventDefault();
    
    $.ajax({
        url: '/route/id/other_route/secret_id',
        type: 'PUT',
        data: $('#form-id').serializeJSON({ useIntKeysAsArrayIndex: true })
      })
      .done(function() {
        // Super Top Secret Code
      });
  }

And this is what I get on the server:

{"array"=>{"0"=>{"value"=>"value"}}}

Disclaimer: I didn't install this with NPM, I tested by copying the javascript directly into my project. I tried both the minified and un-minified versions. I don't know if this would cause problems.

(I'm fighting with webpack currently, will update to NPM when I have this figured out)

@StephenEsser
Copy link
Author

I don't know if this is anymore helpful, but the following HTML serializes into an Array as expected when using useIntKeysAsArrayIndex. I removed the nested value object.

<form id="form-id">
  <input name="array[0]" value="value">
</form>

Returns to the server:

{"array"=>["value"]}

Toggling the useIntKeysAsArrayIndex between false and true with this data structure works as I would expect. But <input name="array[0][value]" value="value"> does not

@marioizquierdo
Copy link
Owner

Yup, based on the way you describe it, there's a bug.

On this HTML:

<form id="form-id">
  <input name="array[0][value]" value="value">
</form>

The following serialization:

$('#form-id').serializeJSON({useIntKeysAsArrayIndex: true});

Should return this:

{"array": [{"value": "value"}]}

But it seems like it's returning this instead (bug!):

{"array"=>{"0"=>{"value"=>"value"}}}

Which is the same as if the useIntKeysAsArrayIndex were disabled. This gives a hint, the error may be that it is not being reclusively applied or something like that. I'll get to it ASAP. Thanks for reporting!

@marioizquierdo
Copy link
Owner

I added a test with exactly this input and everything seems to be working as expected: 7fc7e9b

This means that the bug is not in serializeJSON, but somewhere in you code. I would double check that you don't have a spelling error (although serializeJSON would know about invalid options).

Maybe the issue is in the way you send the ajax request? The jQuery.axaj data parameter is supposed to be a plain object, that will get serialized as "application/x-www-form-urlencoded" by default. That may be doing the undesired transformations. Why don't you try this instead?

  function testFormSubmit(event) {
    event.preventDefault();
    var obj = $('#form-id').serializeJSON({ useIntKeysAsArrayIndex: true });
    // console.log(">>> serialized obj: ", obj); // uncomment this to double check!
    var jsonString = JSON.stringify(obj);
    // console.log(">>> serialized json: ", jsonString); // uncomment this to double check!
    
    $.ajax({
        url: '/route/id/other_route/secret_id',
        method: 'PUT',
        contentType: "application/json; charset=utf-8", // <<== IMPORTANT!!
        data: jsonString
      })
      .done(function() {
        // Super Top Secret Code
      });
  }

I hope this helps your case. I will close this issue as it seems everything is fine with serializeJSON. Good luck!

@StephenEsser
Copy link
Author

Thanks for the help! Your suggestion above works as I would expect.

The real mystery now is why the other serialization library works and this one doesn't when passed directly into the ajax data parameter. I'll continue forward with your example.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants