0

I have a json object and I want to take some of the values from it to create a new object in React.js. However no matter what I try I get errors relating to the value or key being undefined.

Json

{
    "meat":{"drink":"Bovril", "courses":{ "main":"chicken", "pudding":"jelly" },
    "vegetarian":{"drink":"milkshake", "courses":{"main":"cheese","pudding":"ice cream"},
    "vegan":{"drink":"spinach juice", "courses":{"main":"lettuce","pudding":"apple"}
}

Desired results

I would like to dynamically create an object called defaultValues which matches the following if I was to hard code it. As you can see, this is created from the values in the above json file:

const defaultValues: {
    meat: "chicken",
    vegetarian: "cheese",
    vegan: "lettuce"
  }

I have tried the following based on the answer to a similar question, but it doesn't work:

My attempt

const json = Json; //this contains the contents of my json file above

const defaultValues = {};
Object.keys(json).forEach(function(key) {
  defaultValues[key.meat].push([key.courses.main]);
});

Error

I keep getting the following error:

×TypeError: Cannot read property 'push' of undefined

Can anyone advise on how to do this?

Many thanks,

Katie

1
  • 1
    You have a JavaScript object, not a "JSON" object. And the .push() method is for arrays, not plain objects. You're looking for Object.assign() or spread syntax. Commented Apr 1, 2020 at 15:56

3 Answers 3

1

first of all, I corrected your json. After that I iterate the keys of the json object to create the defaultValues object. In your attempt you have been treating an object as an array. Only arrays have the push method.

const json = {
    "meat": {
        "drink":"Bovril", 
        "courses":{ 
            "main":"chicken", 
            "pudding":"jelly" 
        }
    },
    "vegetarian":{
        "drink":"milkshake", 
        "courses":{
            "main":"cheese",
            "pudding":"ice cream"
        }
    },
    "vegan":{
        "drink":"spinach juice", 
        "courses":{
            "main":"lettuce",
            "pudding":"apple"
        }
    }
};

const defaultValues = {};

Object.keys(json).forEach(e => {
  defaultValues[e] = json[e]["courses"].main;
});

console.log(defaultValues);

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much Manuel for your excellent and speedy reply! This works perfectly, and I'm sorry my json was wrong - I wrote a completely different json to simplify my explanation and made a mistake. The only problem I got was that my console.log was showing [object object], but I used the following code to see the results properly and then was able to see it working: JSON.stringify(defaultValues) Thanks again!
1

The reason you are getting an error is because you are using an array method on an object. Your defaultValues is an object {}

The other issue is that json is a string and you would need to parse the string into an object first. You are also missing end curly braces on some of your json.

Here is my take on your code :

const json = `{
  "meat": {
      "drink": "Bovril", "courses": { "main": "chicken", "pudding": "jelly" }},
  "vegetarian": {
      "drink": "milkshake", "courses": { "main": "cheese", "pudding": "ice cream" }},  
  "vegan": {
      "drink": "spinach juice", "courses": { "main": "lettuce", "pudding": "apple" }}
}`;

const menu = JSON.parse(json)

const defaultValues = {};
Object.entries(menu).forEach(function (entry) {
  defaultValues[entry[0]] = entry[1].courses.main;
});
console.log(defaultValues) // -> Object {meat: "chicken", vegetarian: "cheese", vegan: "lettuce"}

Object.entries returns an array with the length of the object keys and an array of both key and value. So it's just a matter of mapping those to defaultValues using the entry[0] as the key and entry[1] as the value.

Edit: adding a working example on codesandbox

3 Comments

Why are you initializing the object as a string then converting it to an object? Feels like an extra step. I've never heard to .entries though seems super useful
Hi Fabrice - many thanks for taking the time to reply to my question. Yet again, I think this is very similar to the other two responses which is great confirmation that it's the right approach. Many thanks again! Katie
@bryanstevens314 JSON is a file format for exchanging data as text so for the sake of completeness, I just wanted to show that you would normally parse the string into a JavaScript object first. People often confuse JSON and JavaScript shorthand declarations because they look the same. I thought this might help someone
1

Not entirely sure I've read your question correctly, but if you're trying to generate

const defaultValues: {
    meat: "chicken",
    vegetarian: "cheese",
    vegan: "lettuce"
}

From this json object - (stuck this through a validator and it didn't come out happy, here's the corrected format)

const Json= {
    "meat": {"drink": "Bovril","courses": {"main": "chicken","pudding": "jelly"}},
    "vegetarian": {"drink": "milkshake","courses": {"main": "cheese","pudding": "ice cream"}},
    "vegan": {"drink": "spinach juice","courses": {"main": "lettuce","pudding": "apple"}}
}

Then the below should work

const json = Json; //this contains the contents of my json file above

const defaultValues = {};
Object.keys(json).forEach(function(key) {
  defaultValues[key] = json[key].courses.main;
});

2 Comments

Thank you so much for your reply! This is almost identical to Manuel's answer which gave me confidence that this is the right way to do it. The only reason why I gave Manuel the tick for the correct answer was because he used => instead of function, which I think might be a newer way of doing things? But to be honest, I would've given it to both of you if I could. Many thanks again for kindly taking the time to help. Much appreciated.
Thanks! And just because it's newer doesnt mean it's better vanilla function declarations are still just as valid

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.