DEV Community

mohamed farid
mohamed farid

Posted on

Use "console.log" with objects becomes tricky

Hi, sometimes there is a problem with using consle.log to log objects, let's discuss it.

Problem

So firstly this happen only with logging Javascript Objects

how to generate the issue?

const ourObject = {
    property: "property_value"
}
console.log(ourObject)
Enter fullscreen mode Exit fullscreen mode

In this situation the expected console output should be something like this

Image description

But what if we have another function that run after this code and make some changes for our object


const ourObject = {
    property: "property_value"
}

console.log(ourObject)

function updateObjectFn(obj){
     obj.property = "property_value_updated"
}

updateObjectFn(ourObject)
Enter fullscreen mode Exit fullscreen mode

The expected output for the console log here should be the same as the prvious console.log result as we call updateObjectFn after console.log(ourObject)

But the log will be something interesting it will show the property as updated even we have updated it after log

Image description

So what is happening, most of the browsers show on the console the current state of the object on the memory not the object at the time of logging it.

And that happen special with object as it Mutable
Same issue happen with arrays as it also objects on Javascript

Solution

In fact there is many solutions for this situation

1. Pass update function a copy of the object to avoid data mutation

for simple objects we can do shallow copy using destructing

const ourObject = {
    property: "property_value"
}

console.log(ourObject)

function updateObjectFn(obj){
     obj.property = "property_value_updated"
}

updateObjectFn({...ourObject})
Enter fullscreen mode Exit fullscreen mode

Image description

if the object is nested we can use some utility tools like Lodash function deepClone

const ourObject = {
    property: "property_value",
    nestedProperty: {
           key: "key_value"
    }
}

console.log(ourObject)

function updateObjectFn(obj){
     obj.property = "property_value_updated"
     obj.nestedProperty.key = "key_value_updated"
}

updateObjectFn(_.cloneDeep(ourObject))
Enter fullscreen mode Exit fullscreen mode

Image description

NOTE: take care about coping too many objects as increase the usage of the memory

By the end Will discuss another approach to avoid mutations without having a deep memory effect.

2. By making Stringify copy of the object

Make a stingify copy of the object before logging it.

const ourObject = {
    date: new Date() ,
    property: "property_value"
}

console.log(JSON.parse(JSON.stringify(ourObject)))

function updateObjectFn(obj){
     obj.date = new Date("1/1/2022")
     obj.property = "property_value_updated"
}

updateObjectFn(ourObject)
Enter fullscreen mode Exit fullscreen mode

Although, it loses some information about the properties on the object of some data types as Example Date here.

Image description

3. Use immutable data types.

There is some Javescript package that provide immutable data types
on an elegant way without having deep effect on the memory usage.

Examples: immutable-js Immer

Same Problem with React devTools.

you Might face this same problem with React devTools
As this screen as the devTools show that the object as
Updated but it is not updated on the screen.

Image description

This issue happen if the state of the application updated directly
without using setState method

As this example here

I think that it, Thanks for reading I hope you enjoyed going throught it🙂.

Any feedback would be greatly appreciated.

Top comments (0)