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

JSON.stringify reactive object cause Error on IOS: json.stringify cannot serialize cyclic structures #1916

Closed
rick-yo opened this issue Aug 21, 2020 · 6 comments
Labels
has workaround A workaround has been found to avoid the problem

Comments

@rick-yo
Copy link

rick-yo commented Aug 21, 2020

Version

3.0.0-rc.6

Reproduction link

https://codesandbox.io/s/nifty-morse-hce62?file=/src/index.js

Steps to reproduce

It works fine on other IOS device, but throw error on IOS 12.0, safari

What is expected?

Not throw error when stringify

What is actually happening?

Throw error


Screenshot url: https://ibb.co/qj1YDyk

@posva
Copy link
Member

posva commented Aug 21, 2020

It looks like iOS 12 still traverses the property __v_reactive even though it is not enumerable and it wouldn't show up on the final JSON.stringify result.

You can create a copy of the value as a workaround:

JSON.stringify({ ...s })

That way the non-enumerable keys will be dropped as they should

@posva posva added the has workaround A workaround has been found to avoid the problem label Aug 21, 2020
@yyx990803
Copy link
Member

yyx990803 commented Aug 21, 2020

Does this happen only on iOS 12.0 or all 12.x? Can someone try it on 12.1?

If it's 12.0 only I'm afraid this is going to be a wontfix since it's technically a bug in the JavaScript Core bundled with iOS 12 and according to stats it's <0.37% of all iOS versions as of April 2020, so I'd expect it to phase out next year.

@posva
Copy link
Member

posva commented Aug 21, 2020

I could only test on 12.1 on Browserstack but I couldn't find in what version this bug was fixed https://en.wikipedia.org/wiki/IOS_version_history#iOS_12

@rick-yo
Copy link
Author

rick-yo commented Aug 22, 2020

I reproduce this problem on IOS 12.4.4 (real device), and IOS simulator 12.0.

@Picknight
Copy link
Contributor

Picknight commented Aug 24, 2020

@luvsic3 You can solve it as follows, I verified it on iOS 12 iPhone 8 Plus simulator:

var seen = [];
const res = JSON.stringify(s, function (key, val) {
  if (val != null && typeof val === "object") {
    if (seen.indexOf(val) >= 0) {
      return;
    }
    seen.push(val);
  }
  return val;
});

@Picknight
Copy link
Contributor

Picknight commented Aug 24, 2020

Root cause speculation:

JSON.stringify() needs to get key-array first, and then get the value. It will trigger the call of Reflect.ownKeys(). The return of ownKeys will not be directly used as the key-array, Enumerable of the attribute will be verified here. But this verification does not seem to be performed on iOS 12.

For this kind of problem, I think if Vue3 tries to solve it, it may cause more problems. So I suggest users to be compatible.

Reference: ECMAScript - JSON.stringify

@github-actions github-actions bot locked and limited conversation to collaborators Nov 6, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
has workaround A workaround has been found to avoid the problem
Projects
None yet
Development

No branches or pull requests

4 participants