38

I have stumbled on a weird issue when trying to recursively set properties on an empty object with the following code:

Simplified code

const birthdays = {};

// Loop -> Passing day, id and birthday
birthdays[day] = day;
birthdays[day][id] = birthday;

Example of day: '01012017'

Example of id: 1547

Example of birthday: {name: John}

Error message

Cannot create property '123' on string '06012017'

I saw some people with Angular having this issue but their answer don't solve anything for me (as is angular specific syntax etc).

5
  • 2
    The error seems pretty clear. What is your question? Commented Jan 6, 2017 at 16:47
  • 1
    @FelixKling I was messing up the init of birthdays[day] with the day itself, using the birthdays[day] = {} fixed it for me. Commented Jan 6, 2017 at 16:49
  • There's no error in that code. It's perfectly valid Javascript. You can do this: birthdays['01012017'] = '01012017' and then this birthdays['01012017'][1547] = {name: 'John'}, and it will NOT trigger any such error. Commented Mar 7, 2021 at 0:37
  • @GetFree - that is a tricky one - but you are right because Strings allow setting (characters) by numeric index causes no error - the code is valid but you can't access that value later birthdays['01012017'][1547] === undefined Commented Apr 7, 2023 at 6:47
  • If the day value is a string let sDay='01012017'; birthdays[sDay]=sDay; then ⚡ sDay.id='birthday' causes the TypeError as scalar system types (String, Number, Boolean,...) in general are "frozen" (can not have any new props assigned). Object.isFrozen('01012017') === true. To avoid this but keep the "string" feeling - a wrapper class could be used: class Value{constructor(v){this.value=v;}toString(){return this.value;}} making birthdays[day]=new Value(day);birthdays[day][1547]={name:"John"} is error free and birthdays[day] has props and String(birthdays[day]) === '01012017' Commented Apr 7, 2023 at 6:55

3 Answers 3

33

Empty Objects need to be individually created before their values are assigned. And use of const is not a good idea here, anyway, it's just my suggestion.

const birthdays = {};
var day = 123;
var id = 21;
var birthday = 2016;
// Loop -> Passing day, id and birthday
birthdays[day] = {};
birthdays[day][id] = birthday;

Sign up to request clarification or add additional context in comments.

2 Comments

It solved my issue! I was messing up the init of birthdays[day] with the day itself, using the birthdays[day] = {} totally worked
Use of const is perfectly fine and best practice here. It means that you are not going to reassign a variable. Don't be confused with immutability of value
6

I had a similar error message TypeError: Cannot create property 'false' on boolean 'false' in Node 14.3.0 (ES 2019), using the new Javascript semicolon-less syntax, with a variable declaration and assignment followed by a destructuring assignment on the next line.

The code that caused the error:

var a = b ()
[c, d] = e ()

Solved by:

var a = b ()
;
[c, d] = e ()

Comments

0

First, define the object:

let birthdays = {};

Then, get the attributes you want to use in that object:

let day = '20210203';
let id = 77;

Afterwards, create a pair of the two attributes (bear in mind the square brackets, that's an ES6 feature to use the variable as a key):

let pair = {[id]: day};

And, finally, form up the main object like this:

birthdays = {...birthdays, ...pair};

And voila, you've added a kvp to an empty object and you won't be getting the "Cannot create property '77' on string '20210203'" error anymore.

4 Comments

This is incorrect. Objects are not iterable so you can't use the spread syntax with them. This will trigger an error: ...birthdays, as well as this ...pair.
where exactly do you see iterations, @GetFree? try all of the lines in your browser console and you will see that there is no error thrown whatsoever.
I did try them. The 3 dots syntax ... requires the value to its right to be iterable. That's why this ...birthdays will throw an error.
@GetFree, the spread operator is valid on both an iterable and an object. You can spread the contents of an array, or spread out the key-value pairs. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.