Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle circular reference with toJS #1860

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Handle circular reference with toJS #1860

wants to merge 1 commit into from

Conversation

jdeniau
Copy link
Member

@jdeniau jdeniau commented Jul 19, 2021

Fixes #1789

List,
Map,
OrderedMap,
Record as ImmutableRecord,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of aliasing the Record name here, can you just make an explicit type in the unit test? (Does that value even need to be explicitly typed?)

Comment on lines +134 to +136
expect(() => simplerTest.toJS()).toThrow(
'Cannot convert circular structure to JS'
);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This behavior surprises me, I would have expected a return of [obj]

}

if (circularStack.has(value)) {
throw new TypeError('Cannot convert circular structure to JS');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of throwing here, how about returning circularStack.get(value) to recreate the cycle?

}

function toJSWithCircularCheck(circularStack, value) {
checkCircular(circularStack, value);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can inline this function since it's only used here

@leebyron
Copy link
Collaborator

leebyron commented Jul 22, 2021

IMHO the original mistake was the value = Seq(value); in toJS() - the original intent was to crawl an entire data structure — Immutable or plain JS — replacing Immutable ones with plain JS ones deeply. Converting plain JS to Seq along the way simplified the implementation, but resulted in hard to reason about conversions like this one.

My advice here is to attempt to resolve the cycle instead of simply throwing, since it's probably not uncommon to find this kind of cycle in regular JS objects stored within a collection, but perhaps we should consider a future breaking change which simply stops the recursive conversion when it finds a non-Immutable.js collection/value

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

toJS() crashes when certain self-referencing objects are stored in an Immutable container
2 participants