1

An example to show what I mean exploring a deeply nested object structure.

This is a real code I deal with today (it is vue but that is irrelevant to my question)

data() { 
    return {
        customer: {},
        settings: [],
        task: {},
        ...
        }
}

I read the code several times to find out the customer is created by spread operator to combine some objects returned from 2 REST api calls!!! The same goes to task & settings.

Object Literal and spread operator makes creating deeply nested object very easy. But from time to time I have to read the code several times to find out "where did I get that property" or "why nobody tells me this object has such such property (normally deeply nested)". So is there anyway to help me explore what properties customer has when I see customer: {} ?

Requiring the original author to write a thorough document is much easier to say than done. The same goes to setting a hard rule like no more than 3 nested levels.

BTW, my question is not about how to access deeply nest object and avoid the error "Cannot read property 'foo' of undefined"

Using an example from "Accessing Nested Objects in JavaScript").

user = {
    id: 101,
    email: 'jack@dev.com',
    personalInfo: {
        name: 'Jack',
        address: {
            line1: 'westwish st',
            city: 'wallas',
            state: 'WX'
        }
    }

After all there are some best practices to access the nested object, e.g. How can I access and process nested objects, arrays or JSON? or I can use lodash get

So my question is is there any recommended way(s) to make working with deeply nested object less painful, in general and javascript in particular?

-------- update --------

When I said "Requiring the original author to write a thorough document is much easier to say than done." There are couple of reasons except for the obvious one that the original author may not have time/resource/energy to do that.

The other reasons (happen to me a lot) include, the original author has quit the job or there are more than one designers to this data structure and the latecomers added something that turned to be totally unnecessary because they didn't understand the original design in the first place. I am sure anyone who inherits a legacy system can relate to that.

And in javascript world a legacy system can mean something developed in 2018!

9
  • 2
    This is just how programming is. Sometimes this complexity cannot be avoided. There's no simpler "call wrap" than simply accessing properties. The only thing you should be asking yourself is "did these guys design their data structures/maps well? Why do I have to access it in this manner?" and as I said, sometimes the answer is "because it's needed". Complex systems require complex access that's usually facilitated by wrappers. If accessing user.personalInfo.address.city happens often, well, just wrap it inside getCity.
    – Daniel M
    Feb 27, 2020 at 0:57
  • But like I said accessing isn't my biggest concern. My biggest concern is I can't know for sure what properties those deeply nest object has. Feb 27, 2020 at 2:21
  • Have you considered Typescript, or a strongly typed language like Java? Easier to figure out what properties are available. Alternatively, when I was starting in JavaScript, just set breakpoints in the debugger and look at what myUser has.
    – user949300
    Feb 27, 2020 at 2:31
  • As a matter of fact I did (in long run), but right now I am thinking about using jsdoc Feb 27, 2020 at 2:32
  • You may want to revise the question title to match what you want to ask. I mean, from the title and the first part of the question, it sounds like you want to ask about how to get deeply nested data more easily. But then midway through the question, it seems like you change the question to being about how to.. explore the structure of an object, I think? Whatever the case, it'd probably help to clarify.
    – Nat
    Feb 27, 2020 at 2:43

1 Answer 1

4

Several comments mostly touch on this answer, but I believe it is a complete answer to the question and I am posting it as such.

Complexity isn't always avoidable

Object Literal and spread operator makes creating deeply nested object very easy. But from time to time I have to read the code several times to find out "where did I get that property" or "why nobody tells me this object has such such property (normally deeply nested)"

To some degree, this is a problem of your own making. You've nested a lot of separate objects, and now you're struggling to juggle all these objects and keep track of their overall structure.
Note that by "you", I am assuming I'm talking to the designer of the structure. The next chapter addresses what to do when you are not the designer of the structure.

You need to strike a balance in how much you separate your data in different objects. On either extreme, it becomes problematic. When not separated enough, objects become a big blob of properties which leads to a bulky dataset lacking in logical categorization. When overly separated, the excessive categorization created a mind maze of the nested levels you must traverse to find your figurative pot of gold at the end.

Like with most things, the best solution is found in the middle, where you try to minimize both issues as best as you can. But in some cases, it's just not possible to sufficiently avoid both issues at the same time.

Taking a personal example of a customer who wanted to perform one web request once every 6 months, which would contain the entire logistical planning for the entire company's workforce for the coming 6 months, including custom logic patterns per order and full staff scheduling, there is simply no way to design an input JSON file that is not massive or convoluted. The posed scenario (one request to solve it all) made it impossible to avoid.

Similarly, you may be in a situation where the complexity is inherent to the posed use case, and then you can't really avoid it.


Consumers rely on designers

Requiring the original author to write a thorough document is much easier to say than done.

If you are consuming a structure developed by someone else, without them having documented it, you are essentially at the mercy of how they chose to design the structure.
This can indeed become a guessing game which sometimes throws you curve balls, but there is no efficient way for you to solve this, other than spurring on the original creator to document their creation.


Strong typing

So my question is is there any recommended way(s) to make working with deeply nested object less painful, in general and javascript in particular?

Object Literal and spread operator makes creating deeply nested object very easy. But from time to time I have to [..] to find out [..] "why nobody tells me this object has such such property (normally deeply nested)"

The main language feature you're looking for that helps drive down the complexity of development is called strong typing. Javascript is a weakly typed language by design.

Having a strongly typed language makes it easier for the IDE to fact-check your code and confirm that you are accessing properties and methods that actually exist. This also expands the abilities of your Intellisense, which is a tremendous help in ensuring that you reference the correct properties/methods and don't need to remember their exact spelling by heart.

Some IDEs have an Intellisense which can still judge the usage of a given Javascript variable to infer which properties can reasonably be expected to exist; but it's an estimate which doesn't always account for all fringe cases and is wholly incapable of inferring structures beyond its scope (e.g. JSON received from an external source).

The easiest way to alleviate your problems is to switch over to Typescript. Technically, Typescript doesn't actually provide strong typing, but it does provide static typing and a more robust OOP system (classes/interfaces), both of which will lead to a much improved experience in terms of knowing which properties/methods you can find on any given variable.
Typescript will get compiled into Javascript, which means your application can run in the exact same environment as if you'd been developing in JS directly. You can think of Typescript as a "typesafe space" for development.

2
  • Hi thanks for answering my question! Since I already got 3 close votes I did not expect to get a long answer like yours at all! About typescript, as one comment pointed out and I already replied I did not prepare for that yet. My team is not ready yet so I have decided to use jsdoc from now on. About asking the original author to write the document I updated my question why it is not easy. Feb 27, 2020 at 12:16
  • I would suggest you reconsider using TypeScript. The nice thing about TypeScript is that any valid javascript is also valid TypeScript. So you can "convert" your project to TypeScript by simply renaming all .js files to .ts files. Then you can slowly start adding types to files as needed. There are many article out there about how to do this. This one seems pretty good: apiumhub.com/tech-blog-barcelona/… for example.
    – Blake
    Feb 27, 2020 at 12:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.