DEV Community

Cover image for Recurrently loop an object in JS - util function #1
Schemetastic (Rodrigo)
Schemetastic (Rodrigo) Subscriber

Posted on

Recurrently loop an object in JS - util function #1

Currently, I'm working on some personal projects and I thought it was a good idea to share some code I need for my them, and also some things I'm learning along the way, so I'll be sharing more of that soon. I hope you find it useful too! πŸ˜‰

Today I'm sharing with you a utility function to help you loop through nested objects, on each iteration of the object you can run a callback and get useful data.

Use case examples:

  • Filter or sorting data of an object
  • To help you navigate through a directory tree UI which is represented in an object
  • Handle nested options in a UI
  • Handle categories and subcategories
  • Looping through data when pulled from a database

loopObj utility function

You can just copy and paste these functions

/**
 * Loops an object recurrently
 * @param {Object} obj the object to be looped
 * @param {Function} callback a function that will run on each iteration
 */
function loopObj(obj, callback, path = [], nestLevel = 0){
  // validate params (`path` and `nestLevel` are added automatically)
  if(getType(obj) != "object"){
    throw TypeError("The `obj` argument is not an object")
  }
  if(getType(callback) != "function"){
    throw TypeError("The `callback` argument is not a function")
  }

  // Loop the object
  for (let key in obj){
    // Run the callback
    callback(key, obj[key], obj, path, nestLevel)
    // Loop a nested object
    if(getType(obj[key]) == "object") loopObj(obj[key], callback, [...path, key], nestLevel + 1)
  }
}

/**
 * A method to detect data types more accurately
 * Credits: Chris Ferdinandi, https://gomakethings.com/
 * @param {*} data the data to be verified
 * @returns {String} the data type
 */
function getType(data){
  return Object.prototype.toString.call(data).toLowerCase().slice(8, -1)
}

/**
 * License: MIT, https://opensource.org/license/mit
 * Copyright (c) 2024 Rodrigo Isaias Calix
 */
Enter fullscreen mode Exit fullscreen mode

How to use it:

Example snippet:

// example object
const products = {
  computers: {
    laptop: 20,
    desktop: 15,
    mini: 8
  },
  cameras: 20,
  externalDevices: {
    keyboard: {
      usb: 45,
      bluetooth: 25,
    }
  }
}

// calling the function
loopObj(products, (key, value, obj, path, nestLevel)=>{
  console.log(key, value, path, nestLevel)
});
Enter fullscreen mode Exit fullscreen mode

This will output something like this:
a list of console outputs showing what the loopObj function returns

When calling the loopObj function, as the first argument you must pass the object you want to loop, and as the second, a callback. On each iteration, the callback will pass 5 arguments in this order:

  • key (string), the current key property of the object
  • value (any), the value of that property (e.g. a nested object or any other value that it has)
  • obj (object), the object that is currently being looped (either be the parent or a nested object)
  • path (array), the path of the current item being looped
  • nestLevel (number), starting from 0 (the root), it tells you how deep the level of the current loop is.

If you found this useful, I'll be sharing more content like this on DEV!

You can also find me on X: https://x.com/schemetastic

And remember to save it for later πŸ”–

Top comments (0)