Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON.parse: unexpected non-whitespace character after JSON data

I wish to create a JSON object that is derived from the selected options of 4 select menus. These menus may have options selected when loaded (due to a server side technology) or may have no options selected whatsoever! Once the page is loaded using $(document).ready() my script runs… however I’m getting some problems with the JSON object “JSON.parse: unexpected non-whitespace character after JSON data

I want my JSON to have the following structure

selObj = {

    category: selectedCategory, // we can only have 1 category, this isn’t giving me a problem…

    catOptions:{
        optionValue:discountValue, // we can have many of these
        optionValue:discountValue,
        optionValue:discountValue
    },

    tariff:{
        tariffValue:discountValue, // we can have many of these
        tariffValue:discountValue
    },

    tarOptions:{
        tarOption:discountValue, // we can have many of these

    }

};

Okay here’s my function, I’ve removed some items here to simplify, but I’m passing an original empty object into the function as an argument and then hoping to amend this as I will want to pass the JSON object back to the server if/when the select menus are changed… but for now we’re just dealing with the page loading… the function also shows the values or what is selected in a dynamic table that is created using a function called defaultTable() just ignore that for now, it’s the populating of the JSON object I’m interested in (and having problems with).

var selectMenuArray = ["cat", "catOpt", "tariff", "tariffOpt"], // these are the IDs of the select menus...     
selObj = {};

function setUpTable(selectArray, theObj){

    // okay, if we enter the page and and the user already has a tarif selected (so it is shown in the menus) we wish to show the table with the 
    // default/original values...

    var currentSelect,
        catA = [],
        catOptA = [],
        tarA = [],
        tarOptA  = [],
        catOptForObj,
        tariffForObj,
        tariffOptForObj,
        temp1 = {},
        temp2 = {},
        temp3 = {},
        i;

    // loop through the 4 menus and see what is selected
    for(i=0;i<selectArray.length;i++){
    // let's look at the options to see if any are selected by looping through the <option>
        currentSelect = document.getElementById(selectArray[i]);

        for(j=0;j<currentSelect.length;j++){
            // do we have an options with the selected attribute?
            if(currentSelect.options[j].selected == true){
                // okay, we need to make sure the table is shown then the correct values are shown?
                // we know what the Menu is... selectArray[i], and this is the text... currentSelect.options[j].
                // lets build up whet's selected in Arrays...
                switch(selectArray[i]){
                    case "cat":
                        catA.push(currentSelect.options[j].value);
                        break;
                    case "catOpt":          
                        catOptA.push(currentSelect.options[j].value);
                        catOptForObj = catOptForObj + '"' + currentSelect.options[j].value + '":"' + "% to come later" + '",';
                        break;
                    case "tariff":
                        tarA.push(currentSelect.options[j].value);
                        tariffForObj = tariffForObj + '"' + currentSelect.options[j].value + '":"' + "% to come later" + '",';
                        break;  
                    case "tariffOpt":
                        tarOptA.push(currentSelect.options[j].value);
                        tariffOptForObj = tariffOptForObj + '"' + currentSelect.options[j].value + '":"' + "% to come later" + '",';
                        break;  
                    default:
                    // no default?
                }
            }
        }
    }

    // now we can build the table
    if(catA.length > 0 || catOptA.length > 0 || tarA.length > 0 || tarOptA.length > 0){

        // show table...
        $("#dynamicTableHolder table").css("visibility","visible").hide().fadeIn('slow');

        for(i=0;i<selectArray.length;i++){  
            switch(selectArray[i]){ 
                case "cat":
                    defaultTable(catA, "dtCats");
                    theObj.cat = catA[0];
                    break;
                case "catOpt":          
                    defaultTable(catOptA, "dtTariffs");
                    temp1 = '"{' + catOptForObj.substring(0, catOptForObj.length-1).replace(/undefined/g, "")  + '}"'; 
                    theObj = jQuery.parseJSON('"catOptions":' + temp1);
                    break;
                case "tariff":
                    defaultTable(tarA, "dtCatOpts");
                    temp2 = "{" + tariffForObj.substring(0, tariffForObj.length-1).replace(/undefined/g, "") + "}";
                    //theObj = jQuery.parseJSON('"tariff":' + temp2);
                    break;  
                case "tariffOpt":
                    defaultTable(tarOptA, "dtTariffOpts");
                    temp3 = "{" + tariffOptForObj.substring(0, tariffOptForObj.length-1).replace(/undefined/g, "") + "}";
                    //theObj = jQuery.parseJSON('"tarOptions":' + temp3);
                    break;  
                default:
                // no default?
            }
        }
    }

}

I’m having problems with making the JSON object, what I’m trying to do is concatenate strings whilst looping, then covert these to objects using the jQuery.parseJSON method… however I’m not doing this correctly. I’ve even tried changing the quotation marks when creating temp1.

I know this is complicated and I may be asking a lot but can anyone see what I’m doing wrong. I’m not that familiar with jQuery.parseJSON so any advice would be great as I think I’m going mad!

If I'm being vague or not explaining myself well please say so... I've also put this on fiddle... http://jsfiddle.net/itakesmack/JSRt7/1/

PLEASE NOTE THIS IS A WORKING PROGRESS SO SOME ITEMS MAY BE MISSING OR NEED TO BE DEVELOPED (or I may have other bugs... but I hope not).

like image 608
Mike Sav Avatar asked Apr 21 '12 10:04

Mike Sav


1 Answers

You're feeding parseJSON() a string that looks like '"catOptions":"{"A":"B","C":"D",}"' parseJSON() wants something that looks like this '{"catOptions":{"A":"B","C":"D"}}'

You've got a few problems to deal with if you are going to build the JSON by hand.

To fix your error you don't want to wrap your {key:value} in quotes, they are being broken by the quotes inside catOptForObj

You'll need to escape values you are building OptForObj strings with if they may contain double quotes

You are basically building your string like this:

s = s + '"' + A '":"' + "B" + '",';

which will produce something like "A":"B","C":"D",

Commas should only exists between values. One way to do this is check to see if s is empty first, and only append it to s before your additional value. Something like:

s = (s.length?(s+','):'') + '"' + A + '":"' + "B" + '"';

What would be best is to rely on a built in function like JSON.stringify as suggested in the comments

like image 89
Pete Avatar answered Sep 20 '22 18:09

Pete