5
votes

I use fullcalendar jquery plugin from http://arshaw.com/fullcalendar/ and I use knockout js on my website.

I added the event array what is the source of the calendar. The user can modify the events (array).

Then I want to serialize the event array, send by ajax, but I can not, because the calendar modifies my array, and puts an cycle into the source array. How can I remove the changes. Why is there a cycle in my array? I read, may be there is an DOM object in this.

Chrome sendrequest error: TypeError: Converting circular structure to JSON

var a = [];
a.push({
  title: "Event2",
  start: "2013-09-05"
});
a.push({
  title: "Event2",
  start: "2013-09-15"
});

$("#calendar").fullCalendar({
  events: a,
  header: {
    left: "title",
    center: "",
    right: "today prev,next"
  },
  editable: false
});

console.log(JSON.stringify(a));

TypeError: Converting circular structure to JSON

How can I fix it? What is the cause of the cycle?

fiddle example, you can see my problem:

http://jsfiddle.net/erbsaag/XC3NH/1

2
Your fiddle seems to work for me, in Chrome. The console shows [{"title":"Event1","start":"2013-09-23"},{"title":"Event2","start":"2013-09-24"}] - Vlad
at the first writeout, but after that I added to the calendar I should see Uncaught TypeError: Converting circular structure to JSON exception - Lajos
Why don't you copy your array and feed that copy to the calendar? - Vlad
if you examine "a" in the debugger before you stringify, you'll see that a[0].source.events === a. Like @Vlad said, you can give calendar a copy of "a", like here jsfiddle.net/mvayngrib/XC3NH/2 - Mark Vayngrib
You could save it in string form before you pass it to the calendar. Then you don't have to deal with the issues of cloning an array of objects. - Vlad

2 Answers

1
votes

The plugin is modifying your data.

If you run

console.log(a)

before your console.log you can see the issue. One solution is to only return the fields you need, and not return the fields which have cyclical recursions.

Example:

console.log(JSON.stringify(a.map(function(ai) { return {title: ai.title, start: ai.start}})));
0
votes

Please refer to this question: JSON.stringify, avoid TypeError: Converting circular structure to JSON

Here is a function adapting that answer into a simple reusable one-liner:

const jsonStringifySafe = (o) => {
    // Almost as seen in stackoverflow.com/questions/11616630
    var cache = [];
    let retv = JSON.stringify(o, (key, value) => {
        if (typeof value === 'object' && value !== null) {
            if (cache.indexOf(value) !== -1) {
                // Circular reference found, discard key
                return;
            }
            // Store value in our collection
            cache.push(value);
        }
        return value;
    });
    cache = null;

    return retv;
}

usage:

console.log(jsonStringifySafe(a));

Example: http://jsfiddle.net/felyper/XC3NH/17/