1

I am having some trouble with a JSON object I receive from my server. Using console.log on the JSON object correctly shows the JSON object I sent from the server, but when I try to iterate over the keys it starts acting strange. See below.

> console.log(promotions);
{"promotion1":{"color":"white","backgroundColor":"red","text":"from promotion server"},"promotion2":{"color":"purple","backgroundColor":"yellow","text":"from promotion server2"},"promotion3":{"color":"green","backgroundColor":"black","text":"from promotion server3"}}

> for (p in promotions) { console.log(p); }
0
1
2
3
4
... (continues)
264
265
266
bold
strip
stripColors
trap
zalgo
zebra
rainbow
random
america
reset
dim
italic
underline
inverse
hidden
strikethrough
black
... (continues)
magentaBG
cyanBG
whiteBG

A few more details:

I am sending a request from a ExpressJS server using http.request to another ExpressJS server, which then returns the "promotion" JSON object. I have not been able to tell if it somehow gets corrupted underway (I might have set the encoding wrong?).

Testing using the same JSON object but hardcoded instead of sending it from the other server, gives the correct response.

Thanks!

ReturnToZero
  • 375
  • 1
  • 3
  • 16
  • What does `console.dir(promotions)` show you? – Pointy Apr 10 '17 at 19:33
  • Also what is the context for the `console.log()` stuff in your question? Where do they appear in your code? – Pointy Apr 10 '17 at 19:35
  • 1
    `for ...in` loops also include non-enumerable keys, and have no guaranteed order ? – adeneo Apr 10 '17 at 19:36
  • console.dir(promotions) gives: '{"promotion1":{"color":"white","backgroundColor":"red","text":"from promotion server"},"promotion2":{"color":"purple","backgroundColor":"yellow","text":"from promotion server2"},"promotion3":{"color":"green","backgroundColor":"black","text":"from promotion server3"}}' – ReturnToZero Apr 10 '17 at 19:41
  • 3
    Your JSON is still a string, you're seeing the properties that a typical string has, as well as the indices to each character. – RemcoGerlich Apr 10 '17 at 19:44

2 Answers2

4

Your promotions value is the string representation of the JSON. So when you do your for loop, it iterates through it as a string.

var promotions = '{"promotion1":{"color":"white","backgroundColor":"red","text":"from promotion server"},"promotion2":{"color":"purple","backgroundColor":"yellow","text":"from promotion server2"},"promotion3":{"color":"green","backgroundColor":"black","text":"from promotion server3"}}';

for (var p in promotions) {
  console.log(p);
}

For why it does this, see this related question (although the truth is its just a weird consequence of the fact that strings are arrays behind the scenes in which case you should look at this answer)

If you do

var promotions = '{"promotion1":{"color":"white","backgroundColor":"red","text":"from promotion server"},"promotion2":{"color":"purple","backgroundColor":"yellow","text":"from promotion server2"},"promotion3":{"color":"green","backgroundColor":"black","text":"from promotion server3"}}';
  
// convert string representation of JSON into actual object
var promotionsObject = JSON.parse(promotions);

for (var p in promotionsObject) {
  console.log(p);
}

It should work as expected. Just keep in mind if you want to go through each object, and print the properties of those, you'll need to do extra work. See Printing nested JSON without using variable names

Community
  • 1
  • 1
aug
  • 11,138
  • 9
  • 72
  • 93
0

Try filtering out the properties that belongs to prototype

for (var p in promotions) {
  if (promotions.hasOwnProperty(p)) {
    console.log(p);
  }
}
AlexanderB
  • 879
  • 9
  • 12