1

i am struggeling to create an object array from two input-groups, each group has 3 inputs with data-side = left/right each input has class "elm" and data-pos = a/b/c

<input class="elm-left elm" name="l1" data-pos="a" data-side="left"/>
<input class="elm-left elm" name="l2" data-pos="b" data-side="left"/>
<input class="elm-left elm" name="l3" data-pos="c" data-side="left"/>

<input class="elm-right elm" name="r1" data-pos="a" data-side="right"/>
<input class="elm-right elm" name="r2" data-pos="b" data-side="right"/>
<input class="elm-right elm" name="r3" data-pos="c" data-side="right"/>

desired output is:

[
 {
  "name":"title1",
  "data":[
   {
    "left" :{"A":10,"B":10,"C":10},
    "right":{"A":20,"B":20,"C":20}
   }
  ]
 }
]

my output is:

...,"data":[
 {
  "left":{"A":20,"B":20,"C":20},
  "right":{"A":20,"B":20,"C":20}
 }
]
var sides = {};
var info  = {};
$(".elm").each(function () {

  var pos   = $(this).data('pos').toUpperCase(); //a,b,c
  var side  = $(this).data('side'); //left, right
  var val   = $(this).val();

  info[[pos]] = val;

  sides[side] = info;
});

data.push(sides);
5
  • 2
    Please post the relevant HTML too. Regardless, it looks like you only have one info set for both sides, with values inserted to it regardless of their "side". In addition, you are assigining sides[side] = info but info is an object so it is not cloned. At the end of the execution, sides['left'] and sides['right'] both refer to the exact same object. Commented Feb 9, 2022 at 6:48
  • info[side] = { [pos] : val } with data.push(info); looks better but leads to "data":[{"left":{"H":"10"},"right":{"H":"20"}}] Commented Feb 9, 2022 at 7:16
  • 1
    info[side] = overwrites existing values, you need info[side][pos] = after initializing both side objects. I don't know where the "H" came from, if you are trying a new approach then add it fully inside the question. Commented Feb 9, 2022 at 7:35
  • if i replace info[side] with info[side][pos] an error is thrown: info[side] is undefined Commented Feb 9, 2022 at 7:47
  • 1
    You need to initialise a new object for info[side] before you can use info[side][pos]: info[side] = info[side] || {} Commented Feb 9, 2022 at 8:08

1 Answer 1

2

You need to initialise a new object for info[side] before you can use info[side][pos]

info[side] = info[side] || {}

this is a common pattern to either use the existing value if there is one or create a new one object if needed.

You can then use this object directly without the need for the info variable which was getting re-used for different sets of values.

var sides = {};

$(".elm").each(function () {

  var pos   = $(this).data('pos').toUpperCase(); //a,b,c
  var side  = $(this).data('side'); //left, right
  var val   = $(this).val();

  sides[side] = sides[side] || {};
  sides[side][pos] = val;
});

var output = { name: "title1", data: [] };
output.data.push(sides);

console.log(JSON.stringify(output))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="elm-left elm" name="l1" data-pos="a" data-side="left" value="20"/>
<input class="elm-left elm" name="l2" data-pos="b" data-side="left" value="20"/>
<input class="elm-left elm" name="l3" data-pos="c" data-side="left" value="20"/>

<input class="elm-right elm" name="r1" data-pos="a" data-side="right" value="20"/>
<input class="elm-right elm" name="r2" data-pos="b" data-side="right" value="20"/>
<input class="elm-right elm" name="r3" data-pos="c" data-side="right" value="20"/>

Sign up to request clarification or add additional context in comments.

2 Comments

Amazing, works like a charm. I have never seen sides[side] = sides[side] || {}; and without your help i would have never solved it this way. Thanks a lot for your help! Also thanks to Noam for pointing me the right direction.
To explain the meaning of sides[side] = sides[side] || {};: The '||' operator is logical OR, so its checks the value of sides[side]. If it's already an initilaized object then that's the value assigned back to sides[side] so it just remains the same object. If it's undefined, then the OR operations treats is as false-y and returns the other operand instead, in this case an empty object {}. That object is assigned to sides[side].

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.