# Looping throug nested object - map, reduce

**URL:** <https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470>\
**Category:** JavaScript\
**Created:** [November 12, 2021, 5:09pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470 "2021-11-12T17:09:19Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![GM\_sql](https://avatars.discourse-cdn.com/v4/letter/g/b4bc9f/32.png) [@GM\_sql](https://forum.codewithmosh.com/u/GM_sql)\
**Post date:** [November 12, 2021, 5:09pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/1 "2021-11-12T17:09:19Z")

</div>

Hello, could anyone help to clean this data - remove quotations around objects and arrays (by using JSON parser)? Ideally recursively, but 1 level deep is also fine for me.

```auto
const data = [
    {
        "post_id":8,
        "type":1,
        "author":"Marta",
        "categories":"[\"ludzie\"]",
        "tags":"[\"accesories\",\"handcraft\"]",
        "featured_img":"{\"file\": \"1.jpg\", \"2x\": null}"
    },
    {
        "post_id":7,
        "type":1,
        "author":"Marta",
        "categories":"[\"ludzie\"]",
        "tags":"[\"accesories\",\"handcraft\"]",
        "featured_img":"{\"file\": \"IMG_1293-2.jpg\", \"2x\": null}"
    }
];

```

---

<div class="post-metadata">

**Author:** ![some\_random\_coder](https://avatars.discourse-cdn.com/v4/letter/s/3be4f8/32.png) [@some\_random\_coder](https://forum.codewithmosh.com/u/some_random_coder)\
**Post date:** [November 15, 2021, 2:28am UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/2 "2021-11-15T02:28:11Z")

</div>

What’s the point of removing the quotes? Are you trying to get a string that looks like this?

```auto
"tags": "[accesories, handcraft]"

```

It seems bizarre to have data that looks like the above. What are you trying to achieve?

Also, what do you by recursively? Are you saying you need to handle nested objects that look like this?

```auto
{
    "featured_img":"{\"file\": \"1.jpg\", \"2x\": null}",
    "foo": {
        "bar": "{\"file\": \"1.jpg\", \"2x\": null}"
    }
}

```

I don’t know where you get the data like that but unless you can’t control the backend, this kind of stuff should be handled in your backend.

Anyway, this is the code for that

```auto
const data = [
    {
        "post_id":8,
        "type":1,
        "author":"Marta",
        "categories":"[\"ludzie\"]",
        "tags":"[\"accesories\",\"handcraft\"]",
        "featured_img":"{\"file\": \"1.jpg\", \"2x\": null}"
    },
    {
        "post_id":7,
        "type":1,
        "author":"Marta",
        "categories":"[\"ludzie\"]",
        "tags":"[\"accesories\",\"handcraft\"]",
        "featured_img":"{\"file\": \"IMG_1293-2.jpg\", \"2x\": null}"
    }
];

const removeLiteralQuotes = (o) => Object.entries(o).reduce((result, [key, val]) => {
  if (typeof val === 'string') {
  	result[key] = val.replace(/"/g, '');
  } else {
  	result[key] = val;
  }
  return result;
}, {})

console.log(data.map(removeLiteralQuotes))

```

---

<div class="post-metadata">

**Author:** ![GM\_sql](https://avatars.discourse-cdn.com/v4/letter/g/b4bc9f/32.png) [@GM\_sql](https://forum.codewithmosh.com/u/GM_sql)\
**Post date:** [November 15, 2021, 8:50am UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/3 "2021-11-15T08:50:27Z")

</div>

Hi, please let me explain the problem and give you more details.  
The output of Mariadb (slightly extended - in comparison to my previous example) is as below. All objects values (both arrays and objects) are surrounded by “”/’’. This is really problematic as I finally need Json object in order to easily inject appropriate data into the template. Please have a look at categories, tags, featured\_img and images (here nested object) keys. They should look like as at the bottom (I also removed escape characters in order to visualize that). Why recursively? - because I don’t know prior the data I would have need (key names, how deep the object is).

**Mriadb**

```auto
const data = [
    {
        "post_id":8,
        "type":1,
        "author":"Marta",
        "categories":"[\"ludzie\"]",
        "tags":"[\"accesories\",\"handcraft\"]",
        "featured_img":"{\"file\": \"1.jpg\", \"2x\": null}",
        "images":'["{\\"file\\": \\"Fiolet i zieleń.png\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": false, \\"alt\\": \\"Piękny obraz\\", \\"figcaption\\": null}","{\\"file\\": \\"Moja Japonia.jpg\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": true, \\"alt\\": \\"aaa\\", \\"figcaption\\": null}"]'
    },
    {
        "post_id":7,
        "type":1,
        "author":"Marta",
        "categories":"[\"ludzie\"]",
        "tags":"[\"accesories\",\"handcraft\"]",
        "featured_img":"{\"file\": \"IMG_1293-2.jpg\", \"2x\": null}",
        "images":'["{\\"file\\": \\"Fiolet i zieleń.png\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": false, \\"alt\\": \\"Piękny obraz\\", \\"figcaption\\": null}","{\\"file\\": \\"Moja Japonia.jpg\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": true, \\"alt\\": \\"aaa\\", \\"figcaption\\": null}"]'
    }
];

```

**expected result**

```auto
const data = [
    {
        ....
        "categories":["ludzie"],
        "tags":["accesories","handcraft"],
        "featured_img":{"file": "1.jpg", "2x": null},
        "images":[{"file": "Fiolet i zieleń.png", "2x": null, "3x": null, "pinIt": false, "alt": "Piękny obraz", "figcaption": null},{"file": "Moja Japonia.jpg", "2x": null, "3x": null, "pinIt": true, "alt": "aaa", "figcaption": null}]
    },
    {
        ....
    }
];

```

---

<div class="post-metadata">

**Author:** ![some\_random\_coder](https://avatars.discourse-cdn.com/v4/letter/s/3be4f8/32.png) [@some\_random\_coder](https://forum.codewithmosh.com/u/some_random_coder)\
**Post date:** [November 15, 2021, 12:00pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/4 "2021-11-15T12:00:11Z")

</div>

Okay, so you have access to the backend. Then, how do you end up getting results like that in the first place?

Since you have an array of objects in Javascript, you must have used JSON.parse. If so, can you show me the string that was passed to JSON.parse?

You don’t want to handle this on your client side. There must be something that you are doing wrong in your backend when encoding data to JSON.

---

<div class="post-metadata">

**Author:** ![GM\_sql](https://avatars.discourse-cdn.com/v4/letter/g/b4bc9f/32.png) [@GM\_sql](https://forum.codewithmosh.com/u/GM_sql)\
**Post date:** [November 15, 2021, 1:21pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/5 "2021-11-15T13:21:52Z")

</div>

Seems everything is ok when it comes to beck-end. Here is part of my query and a screen how Json looks like (not 1:1 comparison to data - but you’ve got the point).

BTW - from Mariadb documentation: In MariaDB JSON strings are normal strings and compared as strings

```auto
    const {lang, slug} = req.params;
    const sql_postBySlug = `CALL get_post_by_slug_3(?,?)`;
    const [post_res, status_d] = await db.query(sql_postBySlug, [lang, slug]);
    res.json(post_res[0]);

```

 ![Bez tytułu](https://us1.discourse-cdn.com/flex020/uploads/codewithmosh/original/2X/d/d2355d2bd534ab512b73fd599c30b32a6758bf09.png)

---

<div class="post-metadata">

**Author:** ![some\_random\_coder](https://avatars.discourse-cdn.com/v4/letter/s/3be4f8/32.png) [@some\_random\_coder](https://forum.codewithmosh.com/u/some_random_coder)\
**Post date:** [November 16, 2021, 12:50am UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/6 "2021-11-16T00:50:08Z")

</div>

Sigh… no matter how much you love JSON type. It will only create more problems for you like this one…  
If I were you I’d just use SQL the good old-fashioned way with a library like knex.js if I didn’t want to learn fully-featured ORM.

Anyway, here’s a duck tape solution for your problem.

```auto
function parseJSONProps(obj) {
  return Object.entries(obj).reduce((result, [key, val]) => {
    switch (typeof val) {
      case 'string':
        try {
          result[key] = JSON.parse(val)
        } catch(e) {
          result[key] = val
        }
        break
      case 'object':
        result[key] = parseJSONProps(val)
        break
      default:
        result[key] = val
        break
    }
    return result
  }, {})
}

const d = parseJSONProps({
  "post_id":8,
  "type":1,
  "author":"Marta",
  "categories":"[\"ludzie\"]",
  "tags":"[\"accesories\",\"handcraft\"]",
  "featured_img":"{\"file\": \"1.jpg\", \"2x\": null}",
  "nested": {
    "post_id":8,
    "type":1,
    "author":"Marta",
    "categories":"[\"ludzie\"]",
    "tags":"[\"accesories\",\"handcraft\"]",
    "featured_img":"{\"file\": \"1.jpg\", \"2x\": null}",
    "nested": {
      "post_id":8,
      "type":1,
      "author":"Marta",
      "categories":"[\"ludzie\"]",
      "tags":"[\"accesories\",\"handcraft\"]",
      "featured_img":"{\"file\": \"1.jpg\", \"2x\": null}"
    }
  }
})

console.log(d.nested.nested.tags)

```

It assumes the JSON string is in a valid format and has some corner cases. But it’s probably good for your use case.

---

<div class="post-metadata">

**Author:** ![GM\_sql](https://avatars.discourse-cdn.com/v4/letter/g/b4bc9f/32.png) [@GM\_sql](https://forum.codewithmosh.com/u/GM_sql)\
**Post date:** [November 16, 2021, 8:28am UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/7 "2021-11-16T08:28:34Z")

</div>

Yeah, more problems than I wish to have. Thank you, it works well 1 level deep, but unfortunately I have objects inside an array (“images”) - in your case (“nested”). Could we also remove quotations here somehow?

```auto
"images":'["{\\"file\\": \\"Fiolet i zieleń.png\\", \\"figcaption\\": null}",
           "{\\"file\\": \\"Moja Japonia.jpg\\", \\"figcaption\\": null}"]'

```

---

<div class="post-metadata">

**Author:** ![some\_random\_coder](https://avatars.discourse-cdn.com/v4/letter/s/3be4f8/32.png) [@some\_random\_coder](https://forum.codewithmosh.com/u/some_random_coder)\
**Post date:** [November 16, 2021, 3:39pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/8 "2021-11-16T15:39:38Z")

</div>

At that point, you are just being unreasonable to keep marching on your crusade.  
Frankly, this ain’t kind of crusade I want to join.

You should really rethink how you design your query. If I remember correctly you already have normalized tables and those JSON types are just coming from the view. This means you are creating problems yourself. You currently don’t have a heterogeneous schema, so why bother using JSON?

Anyway, this hasn’t been thoroughly tested but works for your case.

```auto
function unstringify(val) {
  try {
    const parsedValue = JSON.parse(val)
    switch(true) {
      case Array.isArray(parsedValue):
        return parsedValue.map(unstringify)
      case typeof parsedValue === 'object':
        return Object.entries(parsedValue).reduce((o, [key, val]) => {
          o[key] = unstringify(val)
          return o
        }, {})
      default:
        return parsedValue
    }
  } catch(e) {
    return val;
  }
}

function parse(obj) {
  return Object.entries(obj).reduce((o, [key, val]) => {
    o[key] = unstringify(val)
    return o
  }, {})
}

console.log('TEST unstringify')
const test_data = JSON.stringify({
  str: 'hello',
  num: 1,
  bool: true,
  arr: JSON.stringify([1, 2]),
  arr_arr: JSON.stringify([
    JSON.stringify([1, 2]),
    JSON.stringify([1, 2])
  ]),
  obj: JSON.stringify({ a: 1, b: 2 }),
  obj_with_arr: JSON.stringify({
    a: JSON.stringify([1, 2])
  }),
  arr_objs: JSON.stringify([
    JSON.stringify({ a: 1, b: 2 }),
    JSON.stringify({ a: 1, b: 2 })
  ]),
  arr_obj_with_arr: JSON.stringify([
    JSON.stringify({
      a: JSON.stringify([1, 2])
    })
  ]),
  arr_obj_with_arr_obj: JSON.stringify([
    JSON.stringify({
      a: JSON.stringify([
        JSON.stringify({ a: 1, b: 2 }),
        JSON.stringify({ a: 1, b: 2 })
      ])
    })
  ])
})
console.log(unstringify(test_data).arr_obj_with_arr_obj[0])

console.log('\nTest parse')
const your_data = [
  {
    "post_id":8,
    "type":1,
    "author":"Marta",
    "categories":"[\"ludzie\"]",
    "tags":"[\"accesories\",\"handcraft\"]",
    "featured_img":"{\"file\": \"1.jpg\", \"2x\": null}",
    "images":'["{\\"file\\": \\"Fiolet i zieleń.png\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": false, \\"alt\\": \\"Piękny obraz\\", \\"figcaption\\": null}","{\\"file\\": \\"Moja Japonia.jpg\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": true, \\"alt\\": \\"aaa\\", \\"figcaption\\": null}"]',
  },
  {
    "post_id":8,
    "type":1,
    "author":"Marta",
    "categories":"[\"ludzie\"]",
    "tags":"[\"accesories\",\"handcraft\"]",
    "featured_img":"{\"file\": \"1.jpg\", \"2x\": null}",
    "images":'["{\\"file\\": \\"Fiolet i zieleń.png\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": false, \\"alt\\": \\"Piękny obraz\\", \\"figcaption\\": null}","{\\"file\\": \\"Moja Japonia.jpg\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": true, \\"alt\\": \\"aaa\\", \\"figcaption\\": null}"]',
  }
]
const parsed = your_data.map(parse)
console.log(parsed)
console.log(parsed[0].images)

```

---

<div class="post-metadata">

**Author:** ![GM\_sql](https://avatars.discourse-cdn.com/v4/letter/g/b4bc9f/32.png) [@GM\_sql](https://forum.codewithmosh.com/u/GM_sql)\
**Post date:** [November 16, 2021, 4:17pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/9 "2021-11-16T16:17:11Z")

</div>

Thank you, I really appreciate your time and effort. Will be able to test it later.

Well, I’m trying to be organized thus such query. Item position inside an array defines its order, for many items where orders doesn’t matter I’m using objects. I not sure whether my approach is correct in fact - I don’t have to much experience it that, especially that ~100% courses recommend and rely on Mongodb.

---

<div class="post-metadata">

**Author:** ![some\_random\_coder](https://avatars.discourse-cdn.com/v4/letter/s/3be4f8/32.png) [@some\_random\_coder](https://forum.codewithmosh.com/u/some_random_coder)\
**Post date:** [November 16, 2021, 4:45pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/10 "2021-11-16T16:45:55Z")

</div>

I think you would benefit a lot from taking any modern courses that build a full-stack app.  
Without fundamentals and guidance, it is very easy to head to the road of friction and get lost in there. Knowing when to stop and reevaluate your approach is also valuable.

I might be wrong because I’m not that experienced either. But I can at least tell your approach deviates a lot from the norm.

Anyway, good luck with your journey.

---

<div class="post-metadata">

**Author:** ![GM\_sql](https://avatars.discourse-cdn.com/v4/letter/g/b4bc9f/32.png) [@GM\_sql](https://forum.codewithmosh.com/u/GM_sql)\
**Post date:** [November 17, 2021, 3:21pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/11 "2021-11-17T15:21:44Z")

</div>

Works, thank you. I have the last question on how to implement it into Express and integrate them as now they generates [Object Object]

```auto
const {unstringify, parse} = require("../utils/common")

router.get("/qwerty", (req, res, next) => {

    const data = [
        {"images":'["{\\"file\\": \\"Fiolet i zieleń.png\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": false, \\"alt\\": \\"Piękny obraz\\", \\"figcaption\\": null}","{\\"file\\": \\"Moja Japonia.jpg\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": true, \\"alt\\": \\"aaa\\", \\"figcaption\\": null}"]'},
        {"images":'["{\\"file\\": \\"Fiolet i zieleń.png\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": false, \\"alt\\": \\"Piękny obraz\\", \\"figcaption\\": null}","{\\"file\\": \\"Moja Japonia.jpg\\", \\"2x\\": null, \\"3x\\": null, \\"pinIt\\": true, \\"alt\\": \\"aaa\\", \\"figcaption\\": null}"]'}
    ];

    const post = data.map(parse)

    console.log(post)
    res.send(`<h1>${out}</h1>`)
})

```

**out**

```auto
  {
    post_id: 8,
    type: 1,
    author: 'Marta',
    categories: ['ludzie'],
    tags: ['accesories', 'handcraft'],
    featured_img: { file: '1.jpg', '2x': null },
    images: [[Object], [Object] ]
  },
  {
    post_id: 7,
    type: 1,
    author: 'Marta',
    categories: ['ludzie'],
    tags: ['accesories', 'handcraft'],
    featured_img: { file: 'IMG_1293-2.jpg', '2x': null },
    images: [[Object], [Object] ]
  }
]

```

---

<div class="post-metadata">

**Author:** ![some\_random\_coder](https://avatars.discourse-cdn.com/v4/letter/s/3be4f8/32.png) [@some\_random\_coder](https://forum.codewithmosh.com/u/some_random_coder)\
**Post date:** [November 17, 2021, 5:08pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/12 "2021-11-17T17:08:30Z")

</div>

It’s unclear what you are trying to do. That’s what you get when you toString() objects. If you want to see the JSON representation, use res.json. I’m not familiar with Express, so you need to check the doc.

---

<div class="post-metadata">

**Author:** ![GM\_sql](https://avatars.discourse-cdn.com/v4/letter/g/b4bc9f/32.png) [@GM\_sql](https://forum.codewithmosh.com/u/GM_sql)\
**Post date:** [November 17, 2021, 5:35pm UTC](https://forum.codewithmosh.com/t/looping-throug-nested-object-map-reduce/8470/13 "2021-11-17T17:35:31Z")

</div>

Right, no console.log
