1

I have a very large JSON feed of events that I am pulling into JavaScript via AJAX. Once I have the object in memory, I want to just be able to use that instead of making a new AJAX call each time.

I have a form that allows the JSON events to be filtered. Upon initial filter, my function duplicates the original object (to preserve it), then deletes keys from the new object when they don't match the filter criteria.

This works perfectly the first time the set of functions is run. However, when run again, it appears that the original object is being altered which then triggers a JavaScript error.

When I console.debug the original object, I can see that the first time it runs, it is an object as expected. On further runs, it looks like it's being converted into an array of objects somehow.

I have simplified the code to show the issue here:

json = [{"title": "Title 1","time": 1},{"title": "Title 2","time": 1},{"title": "Title 3","time": 2},{"title": "Title 4","time": 2},{"title": "Title 5","time": 3},{"title": "Title 6","time": 3},{"title": "Title 7","time": 4},{"title": "Title 8","time": 4},{"title": "Title 9","time": 5},{"title": "Title 10","time": 5}];
jQuery('a').on('click touch tap', function(){
    propEvents(json);
    return false;
});
//End prep code for example


function propEvents(json){
    var loadFromMemory = 0;

    if ( loadFromMemory == 0 ){
        globalEventObject = json;
        loadFromMemory = 1;
    }


    console.log('Initial Global Object:');
    console.debug(globalEventObject);

    //Filter the JSON
    filteredEventsObject = eventSearch(globalEventObject);

    //The global object was never filtered, but keys are being removed from it too... I need to store it in memory to start filters from scratch each time.
    console.log('Global Object After Filter:');
    console.debug(globalEventObject);
}


function eventSearch(events){
    var tempObject = events; //May be unnecessary, but for example purposes.

    jQuery(tempObject).each(function(i){
        if ( tempObject[i].time != 3 ){
            console.log('no match: removing this event');
            delete tempObject[i]; //Remove this key from the tempObject
            return;
        }
    });

    tempObject = tempObject.filter(function(){return true;}); //Start the keys from 0 again.
    console.log('Length of filtered object:');
    console.debug(tempObject.length);
    return tempObject;
}

Here it is in CodePen where you can view the console logs. This has me spinning my wheels for a few days now and I just can't wrap my head around it. Any clues would be appreciated.

GreatBlakes
  • 3,971
  • 4
  • 20
  • 28

2 Answers2

3

The line var tempObject = events; doesn't actually clone the object. Instead, it makes a var tempObject point to events, and subsequently, any side effects you have on tempObject also happen on events.

There are plenty of ways to clone objects, see this SO question for details: What is the most efficient way to deep clone an object in JavaScript?

Since you mention you're trying to manipulate a JSON feed, I would suggest

var clone = JSON.parse(JSON.stringify(events))

and manipulaing clone.

Community
  • 1
  • 1
heartyporridge
  • 1,151
  • 8
  • 25
1

JavaScript passes objects as a copy of reference. Follow this post for further details.

StackOverflow

Community
  • 1
  • 1