5

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

n1stre
  • 5,856
  • 4
  • 20
  • 41
Lajos
  • 2,549
  • 6
  • 31
  • 38
  • 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 Sep 23 '13 at 17:14
  • at the first writeout, but after that I added to the calendar I should see Uncaught TypeError: Converting circular structure to JSON exception – Lajos Sep 23 '13 at 17:26
  • Why don't you copy your array and feed that copy to the calendar? – Vlad Sep 23 '13 at 17:37
  • 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 http://jsfiddle.net/mvayngrib/XC3NH/2/ – Mark Vayngrib Sep 23 '13 at 17:44
  • if you copy the array, the calendar does not show the event, why? because that will be an object. if you use the slice, that is neither will be ok. because it will be a reference – Lajos Sep 23 '13 at 17:46
  • 2
    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 Sep 23 '13 at 17:51
  • ohh, It is a good idea, and it works. Is this the best way? – Lajos Sep 23 '13 at 17:57
  • why is there a loop in the array? why does the calendar put a circle in this? – Lajos Sep 23 '13 at 18:29
  • @Vlad can you develop your point about "save it in string form"? thanks – Hao Dec 15 '16 at 15:16

2 Answers2

1

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}})));
Ralph Ritoch
  • 3,260
  • 27
  • 37
0

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/

Felype
  • 3,087
  • 2
  • 25
  • 36