0

Trying to build a simple JSON object that contains an array of objects.

var forms = {};
var form = {};

forms.ID = 1;
forms.PackageName = "MyPackage";
forms.PackageForms = [];

form.Key = "0001XX";
form.Ordinal = 0;
forms.PackageForms.push(form);

form.Key = "0002XX";
form.Ordinal = 1;
forms.PackageForms.push(form);

but this Results in:

{"ID":1,"PackageName":"MyPackage","PackageForms":[{"Key":"0002XX","Ordinal":1},{"Key":"0002XX","Ordinal":1}]}

I understand why this is happening: var 'form' is still referring to the just pushed object. Without creating a different object for each item how can I reuse the var 'form'? This must be simple but it is eluding me.

UPDATE:

This seems to work and looks pretty clean

    var forms = {};
    forms.ID = 1;
    forms.PackageName = "MyPackage";
    forms.PackageForms = [];

    function Form(Key, Ordinal) {
        this.Key = Key;
        this.Ordinal = Ordinal;
    }

    forms.PackageForms.push(new Form("0001XX", 0));
    forms.PackageForms.push(new Form("0002XX", 1));
4
  • 1
    why not use a new object? it's a simple statement without any side effects. all other solution makes it harder to understand. Commented Dec 6, 2018 at 16:52
  • 1
    Why do you build this structure in such a cumbersome way, property by property, instead of just using an Object literal? Commented Dec 6, 2018 at 16:54
  • @Thomas - I'm testing a webservice with some data, eventually this will be cleaned up, my down and dirty test gave me an odd result though. Commented Dec 6, 2018 at 16:57
  • Seems there are a lot of ways to do it, I found the one way not to do it. Commented Dec 6, 2018 at 17:02

3 Answers 3

1

You can either create a new object each time:

forms.PackageForms.push(form);
form = {};

or you can push a copy of the object:

forms.PackageForms.push(Object.assign({}, form));
Sign up to request clarification or add additional context in comments.

1 Comment

Object.assign() does work. I don't think I will use it but glad to discover it, that could come in handy.
0

The result you observed is the combination of two behaviours:

  • array.push() adds a new reference to the input object. This means that the same object shall be contained into the same array several times.
  • Assigning values to an object's property means you are changing that object.

So, there you are: You are adding the same object to the array several times, and changing (overwriting) its properties twice. That is why you find the same object twice into the array, and it has the last values you assigned to it.

Update

If you want to store different objects into the array, you must instantiate each time a new one, for example with new Object(), and then assign values to its properties.

Comments

0

A more typical way of achieving this in JavaScript is to not declare empty objects ({}) at all, but to use object literal syntax:

let forms = {
  ID: 1,
  PackageName: 'MyPackage',
  PackageForms: [
    {
      Key: '0001',
      Ordinal: 1
    },
    {
      Key: '0002',
      Ordinal: 2
    }
  ]
};

console.log(forms);


Update: from OP’s comment, here’s a rough outline of how I’d go about using map:

let rawFormData = ...;  // From wherever; an array of objects

let packageForms = rawFormData.map(form => {
  // Any processing, local variables, etc required to derive `Key` and `Ordinal` from `form`

  return {
    Key: form.getKey(),          // Or whatever -
    Ordinal: form.getOrdinal()   //   these could be any expression
  };
});

let forms = {
  ID: 1,
  PackageName: 'MyPackage',
  PackageForms: packageForms
};

2 Comments

the eventual object array will be built by looping over a table with a jquery for each.
Instead of using forEach, you could use map (see here for a full explanation of the difference) which returns an array directly. Then just use that array in place of the array literal [ ... ] when you create forms.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.