question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How to set currently-undefined nested structure?

See original GitHub issue

Not really an issue, but hoping for a best practice, perhaps.

> update({}, {a: {b: {c: {$set: true}}}})
TypeError: Cannot read property 'b' of undefined
    at update (/Users/jordan/Code/kiddom/teacherdashboard/node_modules/immutability-helper/index.js:65:44)
    at update (/Users/jordan/Code/kiddom/teacherdashboard/node_modules/immutability-helper/index.js:65:31)
    at repl:1:1
    at REPLServer.defaultEval (repl.js:248:27)
    at bound (domain.js:280:14)
    at REPLServer.runBound [as eval] (domain.js:293:12)
    at REPLServer.<anonymous> (repl.js:412:12)
    at emitOne (events.js:82:20)
    at REPLServer.emit (events.js:169:7)
    at REPLServer.Interface._onLine (readline.js:210:10)

My target doesn’t have all the keys. Is there a clean way to deep-set the structure from source?

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:2
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
hoytechcommented, Apr 20, 2017

I agree, it’s a pretty big pain having to maintain an empty skeleton structure in your state components. The behaviour some of you are suggesting, where it automatically creates the necessary containers to satisfy the update, is called autovivification.

I have created a mostly-compatible module called update-immutable which implements this feature. For example, the use-case that started this ticket:

> update({}, {a: {b: {c: {$set: true}}}})
{ a: { b: { c: true } } }

The problems that @kolodny mentioned are in my experience generally non-issues. If parts of your code assume a key holds an object and other parts assume the same key holds an array, your program is likely to misbehave entirely apart from the autovivification behaviour. The only time it gets kind of weird is if you try to auto-vivify a nested array into existence, which is not supported:

> update({}, {a: {0: {c: {$set: true}}}})
{ a: { '0': { c: true } } }

So don’t do that. Note that autovivifying an array into existence with a push (for example) is fine since it’s obvious you mean that key to be an array:

> JSON.stringify(update({}, {a: {b: {c: {$push: [1,2,3]}}}}))
'{"a":{"b":{"c":[1,2,3]}}}'

(I’m just JSON stringifying so node repl doesn’t abbreviate the deeply nested structure)

Hope this helps.

0reactions
kolodnycommented, Mar 27, 2017

The reason I’m choosing not to implement this is because you really can’t make any assumptions about what an object that isn’t there is supposed to be. Consider the following:

function Foo() { this.bar = true }
Foo.prototype.foos = function() { console.log('fooing ' + this.test ) }
var update = require("immutability-helper")
var o1 = {foo: new Foo, arr: []}

var o2 = update(o1, {foo: {test: {$set: 'thing'}}});
o2.foo.foos() // "fooing thing"

var o3 = update(o1, {arr: {0: {$set: 'value'}}})
o3.arr.map(v => v.toUpperCase()) // ['VALUE']

This runs as expected however if we were to fill the object with plain objects, when they should sometimes be arrays or some object more exotic, things will start falling apart.

This library is meant to be a helper for using objects immutability (hence the name), similarly, you can’t do the following with mutable objects

var obj = {}
obj.a.b.c = 'obj.a.b.c' // Uncaught TypeError: Cannot read property 'b' of undefined
Read more comments on GitHub >

github_iconTop Results From Across the Web

Getting undefined for a nested struct property - Stack Overflow
Try by making Foo it's own struct. package main import ( "fmt" ) // TestStruct a test struct type TestStruct struct { //...
Read more >
Using ES6 To Destructure Deeply Nested Objects in ... - ITNEXT
Alright, so to access property values two levels deep, first wrap the original property inside the top level object (in this case props...
Read more >
Accessing Nested Objects in JavaScript - DEV Community ‍ ‍
Now if you try you access the name, you'll be thrown Cannot read property 'name' of undefined. const name = user.personalInfo.name; ...
Read more >
JSON.stringify() - JavaScript - MDN Web Docs
The JSON.stringify() method converts a JavaScript value to a JSON string, optionally replacing values if a replacer function is specified or ...
Read more >
Check if an Object has a Nested Property in JavaScript
Use dot notation to access the first property and check if it isn't equal to undefined . Use the logical AND operator to...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found