JSON Questions (How to manage, sort, and change JSON)

So I have list of serving sizes and their weights in a JSON object:

var servingsizes={ oz: [ 28.35, '1 oz' ],
  wt1: [ 125, '1 cup, quartered or chopped' ],
  wt2: [ 109, '1 cup slices' ],
  wt3: [ 223, '1 large (3-1/4 inch dia)' ],
  wt4: [ 182, '1 medium (3 inch dia)' ],
  wt5: [ 149, '1 small (2-3/4 inch dia)' ],
  wt6: [ 101, '1 extra small (2-1/2 inch dia)' ],
  wt7: [ 242, '1 NLEA serving' ],
  '100g': [ 100, '100 grams' ],
  '200cals': [ 384.615, '200 calorie serving' ] }

I get this from a SQL table. To be in the table it has to be stringified.

The first issue appears when I parse the data. When that happens the order seems to go alphabetical.
But I want the sorting to go wt1,wt2…wt9, oz, 200cal, 100g

Is there a smart way to do that without manually redefining the JSON?

Another issue is that I want to round the numbers after using them for calculations.
What is the best way to do that?

Right now I am just using a long if then to rebuild the JSON.

if (servingSizeDisplay["wt1"]) {servingSizeDisplay["wt1"]=[Math.round(servingsizes[serving][0]),servingsizes[serving][1]];}

Happy for any ideas or suggestions. :slight_smile:

OK, so the final method I am settling on is to first define the JSON and then loop through it. Checking if the object exists and rounding down if it down, while deleting it if it doesn’t.

//Define object
var servingSizeDisplay={"wt1":[],"wt2":[],"wt3":[],"wt4":[],"wt5":[],"wt6":[],"wt7":[],"wt8":[],"wt9":[],"oz":[],"200cals":[],"100g":[]};


for (var serving in servingSizeDisplay) {

    if (servingsizes[serving]) 
        {servingSizeDisplay[serving]=[Math.round(servingsizes[serving] 
            [0]),servingsizes[serving][1]];}

    else {
       delete servingSizeDisplay[serving];
         }

    } //End loop

Not the best, but it will do for now.

1 Like

JavaScript objects will have its keys sorted in a specific order, so keys might get rearranged. If you want them in order you could use an array like this:

{
    fields: [
        [oz: [28.35, "1 oz"]],
        [wt1: [125, "1 cup, quartered or chopped"]],
        [wt2: [109, "1 cup slices"]],
        [wt3: [223, "1 large (3-1/4 inch dia)"]],
        [wt4: [182, "1 medium (3 inch dia)"]],
        [wt5: [149, "1 small (2-3/4 inch dia)"]],
        [wt6: [101, "1 extra small (2-1/2 inch dia)"]],
        [wt7: [242, "1 NLEA serving"]],
        ["100g": [100, "100 grams"]],
        ["200cals": [384.615, "200 calorie serving"]],
    ];
}

JavaScript also has something called a Map object (which is different from the lowercase map function). A Map is similar to a regular JavaScript object, but it preserves the order of the keys.

Here’s an example of a function that transforms an input from a regular JS object to a Map that has keys in a specific order.

// JavaScript will move these around, putting the key `1` first
const obj = {
    a: 123,
    f: 321,
    z: 432,
    c: 543,
    1: 432
};

// This function takes an object (with keys in any order) and returns a
// map that preserves a specific order.
function orderedObject(o) {
    return new Map([
    	["a", o.a],
        ["f", o.f],
        ["z", o.z],
        ["c", o.c],
        [1, o["1"]]
    ]);
}

const m = orderedObject(obj);

console.log("the (unordered) object is:", obj);
console.log("the (ordered) map is:", m);

I’m wondering if there might be an easier way to accomplish the task though. If you’re interested in trying another way, I could take a look while screensharing.

It’s hard to know without seeing more of the code. I could take a look if you want.

That’s actually a JavaScript object. JSON is a string version of a JavaScript object that uses a special format.

JSON is kind of like a frozen shipping container for JavaScript objects. The code people write uses JavaScript objects, but when the program wants to send those objects over the network or into localStorage, it freezes them and packs them into a box (JSON). That frozen data can’t be easily used when it’s in the frozen box (JSON), so when you want to use the data again (on the other side of the network or after it comes out of localStorage), you unfreeze the JSON and convert it back into a JavaScript object.

The freezing and unfreezing functions work like this:

// Take a JS object and freeze it into a JSON string to send it somewhere
JSON.stringify(someObject);

// Unfreeze a JSON string and turn it back into an object that JS can use
JSON.parse(someJson);

I’ll update this tutorial with a few more examples later.

A quick way to check: if you take any object-looking thing in JavaScript and try to turn it toUpperCase, it will succeed if it’s JSON and fail if it’s an object. Example:

// A JavaScript object has key-value pairs
const obj= {
    name: "Dragon",
    treasure: "100 gems of 4,000gp value each"
};

// A JSON string is just plain text that has a format similar to an object
// (but JSON isn't really an object itself)
const json = '{"name":"Dragon","treasure":"100 gems of 4,000gp value each"}';

// This will work, because JSON is a string, not an object.
json.toUpperCase();

// This will cause an error, because objects can't be made uppercase
obj.toUpperCase();

They look almost the same, but they function differently. :slight_smile:

1 Like

Hmm a lot to think about here. Thanks Josh!

1 Like

I just found out you can render JSON in the console if it is in your app “State”.
Just type in the name of the JSON and press enter.

2 Likes

Nice, that should work for any global variable (anything that isn’t inside of a function).

// These are global because they aren't inside of a function
var num = 127;
var obj = { name: "Frodo" };

// a function will hide information inside of it
function someFunc() {
    // this variable is hidden because it's inside of a function
    var y = 2;
}

(Variables defined with let and const are different from variables defined with var though — let and const variables are only visible inside of the curly braces where they are defined.)


One more tip: you can check to see if something that looks like JSON is JSON by typing this:

typeof foodData;

If it says “string”, then it’s probably JSON. If it says “object”, then it’s a JS object. :slight_smile:

1 Like

Nice! I will make use of typeof. And yeah, I do have some globals in my client side code. I know people frown on them, but they are basically default in PHP.
Not that difficult to keep up with IMO.

1 Like