1

Given the following literal:

"rating":{
"overall": 89,
"atmosphere": 82,
"cleanliness": 91,
"facilities": 86,
"staff": 94,
"security": 91,
"location": 91,
"valueForMoney": 90
},

And the following for/in loop:

for (key in data.rating) {
  if ( key != "overall" ){
    //<div class='ratingbar'><p>" + translateRating(language, key) + "<span class='right bold'>" +  data.rating[key]/10 + "</span></p><div class='bar-wrapper'><div class='bar' style='width:" + data.rating[key] + "%'></div></div></div>
    //current.find('.ratings ul').append("<li class='left'><span class='ratinglabel'>" + translateRating(language, key) + "</span><span class='ratingpercent bold'>" + data.rating[key]/10 + "</span><div class='ratingbackground rounded'><span style='width:" + data.rating[key] + "%'></span></div></li>");
    if ( key == "valueForMoney" ){
      current.find('.ratings ul').append("<li class='left'><span class='ratinglabel'>" + translateRating(language, 'valueForMoney') + "</span><span class='ratingpercent bold'>" + data.rating[key]/10 + "</span><div class='ratingbackground rounded'><span style='width:" + data.rating[key] + "%'></span></div></li>");
    }
    if ( key == "security" ){
      current.find('.ratings ul').append("<li class='left'><span class='ratinglabel'>" + translateRating(language, 'security') + "</span><span class='ratingpercent bold'>" + data.rating[key]/10 + "</span><div class='ratingbackground rounded'><span style='width:" + data.rating[key] + "%'></span></div></li>");
    } 
    if ( key == "location" ){
      current.find('.ratings ul').append("<li class='left'><span class='ratinglabel'>" + translateRating(language, 'location') + "</span><span class='ratingpercent bold'>" + data.rating[key]/10 + "</span><div class='ratingbackground rounded'><span style='width:" + data.rating[key] + "%'></span></div></li>");
    }                           

  }
} 

When I print the values of the object, I'm expecting them to print in a specific order—the same order as my if statements. Instead, "valueForMoney" is always last. The order I'm expecting is:

  1. Value For Money
  2. Security
  3. Location
  4. Staff
  5. Atmosphere
  6. Cleanliness
  7. Facilities
StepUp
  • 27,357
  • 12
  • 66
  • 120
Alessandro
  • 4,405
  • 15
  • 55
  • 108

3 Answers3

3

Keys in an object are not guaranteed to be in order; you'll need to either use an array or a Map to make sure they're in the right order.

If you can, converting your data structure to be an array of objects is the simplest solution:

"rating": [
    { name: "overall", value: 89 },
    { name: "atmosphere", value: 82 },
    ...
]

since you can then loop through them in a guaranteed order.

You could also try converting the object to a Map, although Maps only exist in ES6 so you'd need to transpile if you;re not already. The order of keys in Maps is guaranteed to be the order in which they're inserted, so this would work for your case.

whostolemyhat
  • 3,031
  • 4
  • 32
  • 50
2

Properties order is not guaranteed in JavaScript.

Definition of an Object from ECMAScript 3

4.3.3 Object

An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive value, object, or function. A function stored in a property of an object is called a method.

ECMAScript 6

9.1.11 [[Enumerate]] ()

When the [[Enumerate]] internal method of O is called the following steps are taken:

  1. Return an Iterator object (25.1.1.2) whose next method iterates over all the String-valued keys of enumerable properties of O. The Iterator object must inherit from %IteratorPrototype% (25.1.2). The mechanics and order of enumerating the properties is not specified but must conform to the rules specified below.
Sergey Gornostaev
  • 6,481
  • 3
  • 19
  • 32
1

How about just printing like this without for key in ?

 current.find('.ratings ul').append("<li class='left'><span class='ratinglabel'>" + translateRating(language, 'valueForMoney') + "</span><span class='ratingpercent bold'>" + data.rating.valueForMoney/10 + "</span><div class='ratingbackground rounded'><span style='width:" + data.rating.valueForMoney + "%'></span></div></li>");
 current.find('.ratings ul').append("<li class='left'><span class='ratinglabel'>" + translateRating(language, 'security') + "</span><span class='ratingpercent bold'>" + data.rating.security/10 + "</span><div class='ratingbackground rounded'><span style='width:" + data.rating.security + "%'></span></div></li>");
 current.find('.ratings ul').append("<li class='left'><span class='ratinglabel'>" + translateRating(language, 'location') + "</span><span class='ratingpercent bold'>" + data.rating.location/10 + "</span><div class='ratingbackground rounded'><span style='width:" + data.rating.location + "%'></span></div></li>");
Wedmich
  • 149
  • 9