JSON

JSON (JavaScript Object Notation) allows data to be stored as a string. JSON holds data in a structured way. This structure is called a JSON object. A JSON object consists of a collection of key/value pairs that are contained inside {} brackets. The data that is held in a JSON object is called properties. Properties are separated by a , (comma), as shown below:

{key1:value1, key2:value2, key3:value3}

For example, use the JSON object below to hold to hold a name, phone and email:

{name:"Mary", phone:123456, email:"a@a.com"}

 

To make it more readable, JSON object code can be written over multiple lines, as shown below:

{
    name:"Mary", 
    phone:123456,
    email:"a@a.com"
}

 

A JSON object can be assigned to a JavaScript variable.

let person = {
                 name:"Anne", 
                 phone:123456,
                 email:"a@a.com"
              }

 

To access a JSON object's property we use a "." (dot) between the object and its property. For example, we use the code below to access the name property of the person object:

person.name

Two {} hold an empty JSON object

let emptyJSONObject = {}

Arrow Functions

Arrow functions can return JSON objects. The JSON object needs to be wrapped in () parentheses.

const setDetails = (name, age) => ({name: name, age: age})

let details = setDetails("Mary", 20)
console.log(details.name + "  " + details.age) 

JSON Arrays

JSON data can be held in an array. We use [] brackets to structure JSON arrays, as shown below:

people = [
             {name:"Anne", phone:1111, email:"a@a.com"},
             {name:"Brian", phone:2222, email:"b@b.com"}, 
             {name:"Cathy", phone:3333, email:"c@c.com"}
         ]

// or more commonly, we compact the [] brackets, as shown below

people = [{name:"Anne", phone:1111, email:"a@a.com"},
             {name:"Brian", phone:2222, email:"b@b.com"}, 
             {name:"Cathy", phone:3333, email:"c@c.com"}]

To access an element in the array, we use an array index, as shown below:

people = [{name:"Anne", phone:1111, email:"a@a.com"},
             {name:"Brian", phone:2222, email:"b@b.com"}, 
             {name:"Cathy", phone:3333, email:"c@c.com"}]


console.log("First element of array is: " + people[0])
console.log("Email of second person in array is: " + people[1].email)

The length of a JSON array is got by using its length() method. This can be used to loop through a JSON array inside a for-loop, as shown below:

people = [{name:"Anne", phone:1111, email:"a@a.com"},
             {name:"Brian", phone:2222, email:"b@b.com"}, 
             {name:"Cathy", phone:3333, email:"c@c.com"}]

for(let i = 0; i < people.length; i++)
{
    console.log("Person " + i + " name is:" + people[i].name)
}

Two [] brackets hold an empty JSON array

let emptyJSONArray = []

Normal arrays are valid JSON structures, as shown below:

let jsonStringArray = ["Alan", "Brian", "Colm"]
let jsonNumberArray = [4, 25, 15, 100]

JSON Array Manipulation

Several methods are available that allow us to manipulate the data in a JSON array. We shall use them here without getting into the detail of how arrow functions work. This will be looked at in 2nd year.

Map()

The map() method allows us to run the same function against each item in a JSON array.

The map() method is immutable, which means that it does not change the content of the original array that is being mapped.

Example of map() method (Run example)

<!DOCTYPE html>
<html>
    <head>
        <title>JSON array map() example</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <script>
            let employees = [{forename:"Ann", surname:"Anglesey", role:"IT"}, 
                             {forename:"Brian", surname:"Brown", role:"HR"}, 
                             {forename:"Cathy", surname:"Connolly",role:"HR"}, 
                             {forename:"Dennis", surname:"Doherty", role:"IT"}, 
                             {forename:"Emma", surname:"Eagan", role:"HR"} ] 

            /* Combine forename and surname into a string and save to an array */
            let fullnameArray = employees.map(employee => employee.forename + " " + employee.surname)
            console.log(`Array of strings`)
            console.log(fullnameArray)

            /* New JSON array object with only forename and surname */
            let fullnameJSON = employees.map(employee => ({forename:employee.forename, surname:employee.surname}))
            console.log(`Array of JSON objects`)
            console.log(fullnameJSON) 
        </script>
        
    </head>
    <body>
        <div>View the console output in browser's Web DevTools (F12)</div>
    </body>
</html>

We only ever use the map() method if we are treating all elements of an array identically. A for-loop can achieve the same outcome as a map() method. The difference is that a for-loop requires more code.

Example of a for-loop replacing a map() method (Run Example)

<!DOCTYPE html>
<html>
    <head>
        <title>JSON for-loop replacing map() example</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <script>
            let employees = [{forename:"Ann", surname:"Anglesey", role:"IT"}, 
                             {forename:"Brian", surname:"Brown", role:"HR"}, 
                             {forename:"Cathy", surname:"Connolly",role:"HR"}, 
                             {forename:"Dennis", surname:"Doherty", role:"IT"}, 
                             {forename:"Emma", surname:"Eagan", role:"HR"} ] 

            // let fullnameArray = employees.map(employee => employee.forename + " " + employee.surname)

            // the code below is the for-loop equivalent of the above map()
            
            let fullnameArray = []
            for(let i = 0; i < employees.length; i++)
            {
                fullnameArray[i] = employees[i].forename + " " + employees[i].surname
            }

            console.log(`Array of strings`)
            console.log(fullnameArray)


            // let fullnameJSON = employees.map(employee => ({forename:employee.forename, surname:employee.surname}))
            
            // the code below is the for-loop equivalent of the above map()
            
            let fullnameJSON = []
            for(i = 0; i < employees.length; i++)
            {
                fullnameJSON[i] = {forename:employees[i].forename, surname:employees[i].surname}
            }
            console.log(`Array of JSON objects`)
            console.log(fullnameJSON) 
        </script>
        
    </head>
    <body>
        <div>View the console output in browser's Web DevTools (F12)</div>
    </body>
</html>

filter()

The filter() method creates a new array that contains all elements from the original array that pass the logical conditional that is contained within the filter() method.

The filter() method is immutable, which means that it does not change the content of the original array that is being mapped.

An example of filter() applied to an array of objects (Run Example)

<!DOCTYPE html>
<html>
    <head>
        <title>JSON array filter() example</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <script>
            let employees = [{name:"Ann", role:"IT", salary:100000}, 
                             {name:"Brian", role:"HR", salary:50000}, 
                             {name:"Cathy", role:"HR", salary:60000}, 
                             {name:"Dennis", role:"IT", salary:120000}, 
                             {name:"Emma", role:"HR", salary:30000}]
                         
            let hrEmployees = employees.filter(employee => employee.role === "HR")

            console.log("All Employees")
            console.log(employees)
            
            console.log("HR Employees")                        
            console.log(hrEmployees)
        </script>
        
    </head>
    <body>
        <div>View the console output in browser's Web DevTools (F12)</div>
    </body>
</html>

A for-loop can be used to replace the filter() method. Write code to do this.

reduce()

The reduce() method reduces an array to a single value. This value is the result of applying a given function against an accumulator and each element in the array (from left to right). The accumulator must be set with an initial value. In the examples below, the variable total is the accumulator. In the example below the accumulator is called total and it has been initialised to 0.

The reduce() method is immutable, which means that it does not change the content of the original array that is being mapped.

An example of reduce() applied to an array of objects (Run Example)

<!DOCTYPE html>
<html>
    <head>
        <title>JSON array reduce() example</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <script>
            let employees = [{name:"Ann", role:"IT", salary:100000}, 
                             {name:"Brian", role:"HR", salary:50000}, 
                             {name:"Cathy", role:"HR", salary:60000}, 
                             {name:"Dennis", role:"IT", salary:120000}, 
                             {name:"Emma", role:"HR", salary:30000}]
                         
            let totalSalary = employees.reduce((total, employee) => total += employee.salary, 0)

            console.log("Total salary is: " + totalSalary)
        </script>
    </head>
    <body>
        <div>View the console output in browser's Web DevTools (F12)</div>
    </body>
</html>

A for-loop can be used to replace the some() method. Write code to do this.

Adjust the example code given above and output the mean average salary for each of IT, HR and for all employees, as shown here.

some()

The some() method will return true if at least one item in the array matches a given condition.

The map() method is immutable, which means that it does not change the content of the original array that is being mapped.

An example of some() applied to an array of objects (Run Example)

<!DOCTYPE html>
<html>
    <head>
        <title>JSON array some() example</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <script>
            let employees = [{forename:"Ann", surname:"Anglesey", role:"IT"}, 
                             {forename:"Brian", surname:"Brown", role:"HR"}, 
                             {forename:"Cathy", surname:"Connolly",role:"HR"}, 
                             {forename:"Dennis", surname:"Doherty", role:"IT"}, 
                             {forename:"Emma", surname:"Eagan", role:"HR"} ] 

            let objectContainsName = employees.some(employee => employee.forename === "Cathy")

            console.log(objectContainsName)  // will display true, as the name "Cathy" occurs at least once in the object
        </script>
        
    </head>
    <body>
        <div>View the console output in browser's Web DevTools (F12)</div>
    </body>
</html>

Adjust the code above and test against the forename "Murphy". You should get false as the console output.

every()

The every() method will return true if all of the items in the array matches a given condition.

The every() method is immutable, which means that it does not change the content of the original array that is being mapped.

An example of every() applied to an array of objects (Run Example)

<!DOCTYPE html>
<html>
    <head>
        <title>JSON array every() example</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <script>
            let employees = [{forename:"Ann", surname:"Anglesey", role:"IT", salary:100000}, 
                             {forename:"Brian", surname:"Brown", role:"HR", salary:30000}, 
                             {forename:"Cathy", surname:"Connolly",role:"HR", salary:50000}, 
                             {forename:"Dennis", surname:"Doherty", role:"IT", salary:150000}, 
                             {forename:"Emma", surname:"Eagan", role:"HR", salary:40000}] 

            let minSalaries = employees.every(employee => employee.salary > 10000)

            console.log(minSalaries)  // will display true, as all of the salaries are at least 10000
        </script>        
    </head>
    <body>
        <div>View the console output in browser's Web DevTools (F12)</div>
    </body>
</html>

Adjust the code above and test against a salary > 100000. You should get false as the console output.

Copying a JSONArray

If we assign a new variable to an JSON array, the new variable will point to the exact same array. Any manipulation of the new array will cause the original array's data to also change. We must use the code below to make a new copy of a JSON array:

// Make a copy of origianlJSONArray and place the new data in copyOfJSONArray
let  copyOfJSONArray = JSON.parse(JSON.stringify(origianlJSONArray))

Sorting Objects

Use the inline function below to sort object arrays. A sort can be based on either a string or numerical value.

This method is mutable. It will change the original array.

An example sorting of an array of objects (Run Example)

<!DOCTYPE html>
<html>
    <head>
        <title>JSON array sort() example</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        
        <script>
            let arrayOfObjects = [{name: "Cathy", age: 25}, 
                                  {name: "Anne", age: 22}, 
                                  {name: "Dermot", age: 20}, 
                                  {name: "Bill", age: 21}, 
                                  {name: "Eric", age: 19}]

            // sort by string
            let  ascendingOrderByName = JSON.parse(JSON.stringify(arrayOfObjects))
            ascendingOrderByName.sort((a, b) => a.name < b.name?-1:1)

            let  descendingOrderByName = JSON.parse(JSON.stringify(arrayOfObjects))
            descendingOrderByName.sort((a, b) => a.name < b.name?1:-1)     

            // sort by number
            let  ascendingOrderByAge = JSON.parse(JSON.stringify(arrayOfObjects))
            ascendingOrderByAge.sort((a, b) => a.age < b.age?-1:1)

            let  descendingOrderByAge = JSON.parse(JSON.stringify(arrayOfObjects))
            descendingOrderByAge.sort((a, b) => a.age < b.age?1:-1) 

            console.log("Original data:")
            console.log(arrayOfObjects)
    
            console.log("Ascending order by name:")
            console.log(ascendingOrderByName)

            console.log("Descending order by name:")
            console.log(descendingOrderByName)

            console.log("Ascending order by age:")
            console.log(ascendingOrderByAge)

            console.log("Descending order by age:")
            console.log(descendingOrderByAge)
        </script>
        
    </head>
    <body>
        <div>View the console output in browser's Web DevTools (F12)</div>
    </body>
</html>

Displaying JSON data on a Webpage

It is common to display a JSON array on a webpage. This can be done using a for-loop and document.getElementById().innerHTML

Example showing document.getElementById().innerHTML (Run Example)

<!DOCTYPE html>
<html>
<head>
<title>JSON array as an unformatted table Example</title>
<script>
let cars = [
    {
        model: "avensis",
        colour: "red",
        year: 2017,
        price: 35000
    },
    {
        model: "yaris",
        colour: "white",
        year: 2015,
        price: 1000
    },
    {
        model: "corolla",
        colour: "white",
        year: 2017,
        price: 20000
    },
    {
        model: "avensis",
        colour: "red",
        year: 2015,
        price: 15000
    },
    {
        model: "corolla",
        colour: "black",
        year: 2010,
        price: 4000
    }
]


function viewJSONData()
{
    let htmlString = `<table>`

    cars.map(car =>
    {
        htmlString += `<tr>
                           <td>${car.model}</td>
                           <td>${car.colour}</td>
                           <td>${car.year}</td>
                           <td>${car.price}</td>
                       </tr>`
    })
            
    htmlString += `</table><br>
                   ${cars.length} items found.`
    document.getElementById("cars").innerHTML = htmlString
}
</script>
</head>
<body onload="viewJSONData()">

<div id = "cars">Car details will be listed here.</div>

</body>
</html>

Change the above code so that CSS styling is applied to the table, as shown here.

Change the code above to display the output as an ordered list instead of a table, as shown here.

Nested JSON

A JSON structure can contain other JSON structures.

In the example below, the top-level JSON object contains a name, description and rounds property.

The rounds array contains a JSON object, which has the properties name and questions.

The questions array contains a JSON object, which has the properties, text, correct and choices.

Example showing nested JSON (Run Example)

<!DOCTYPE html>
<html>
    <head>
        <title>Nested JSON object example</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                
        <script>
            countryQuizData = {
                name: "Countries Quiz",
                description: "EU and other countries quiz",
                rounds:
                        [
                            {
                                name: "The EU",
                                questions:
                                        [
                                            {
                                                text: "How many countries are there in the EU?",
                                                correct: 1,
                                                choices:
                                                        [
                                                            "26",
                                                            "27",
                                                            "28"
                                                        ]
                                            }, 
                                            {
                                                text: "Which EU country has the largest population?",
                                                correct: 1,
                                                choices:
                                                        [
                                                            "France",
                                                            "Germany"
                                                        ]
                                            },
                                            {
                                                text: "Which EU country has the smallest population?",
                                                correct: 2,
                                                choices:
                                                        [
                                                            "Luxemburg",
                                                            "Cyprus",
                                                            "Malta"
                                                        ]
                                            },
                                            {
                                                text: "What is the approximate population of the EU?",
                                                correct: 1,
                                                choices:
                                                        [
                                                            "400 million",
                                                            "450 million",
                                                            "500 million",
                                                            "550 million",
                                                            "600 million"
                                                        ]
                                            }
                                        ]  
                            },
                            {
                                name: "World Wide",                  
                                questions:
                                        [
                                            {
                                                text: "Which country has the largest population?",
                                                correct: 2,
                                                choices:
                                                        [
                                                            "Russia",
                                                            "India",
                                                            "China",                                               
                                                            "USA"
                                                        ]
                                            },
                                            {
                                                text: "Which country occupies the largest area?",
                                                correct: 0,
                                                choices:
                                                        [
                                                            "Russia",
                                                            "India",
                                                            "China"
                                                        ]
                                            }
                                        ]
                            }
                        ]
            }


            function viewJSONData()
            {
                let htmlString = `countryQuizData.rounds[0].questions[1].text is  ${countryQuizData.rounds[0].questions[1].text}
countryQuizData.rounds[0].questions[1].choices[0] is ${countryQuizData.rounds[0].questions[1].choices[0]}
countryQuizData.rounds[0].questions[1].choices[1] is ${countryQuizData.rounds[0].questions[1].choices[1]}
The correct answer is ${countryQuizData.rounds[0].questions[1].choices[countryQuizData.rounds[0].questions[1].correct]}` document.getElementById("quiz").innerHTML = htmlString } </script> </head> <body onload="viewJSONData()"> <div id = "quiz"></div> </body> </html>

As shown in the above example, JSON arrays can be of different lengths. For example, round 1 has four questions and round 2 has two questions.

 

The code below shows how we can use a JSON object's property to be an index into a JSON array.

                htmlString += `The correct answer is <strong>${countryQuizData.rounds[0].questions[1].choices[countryQuizData.rounds[0].questions[1].correct]}</strong>`

Write code to show all of the questions and possible answers in the quiz, as shown here. Use map() rather than for-loops.

Write code that replaces each map() in the code above with a for-loop, as shown here.

Map() Versus For-Loop

The above two questions show that, when using nested JSON objects, it is much easier to write and understand the code if we use map() rather than a for-loop

            // map()     
            function viewJSONData()
            {
                let htmlString = `<ul>`
                countryQuizData.rounds.map(round => 
                {
                    htmlString += `<li>${round.name}</li>`
                    htmlString += `<ul>`
                    round.questions.map(question =>
                    {
                        htmlString += `<li>${question.text}</li>`
                        htmlString += `<ul>`
                        question.choices.map(choice => 
                        {
                            htmlString += `<li>${choice}</li>` 
                        })
                        htmlString += `</ul>` 
                    })
                    htmlString += `</ul>`
                })
                htmlString += `</ul>`
                document.getElementById(`quiz`).innerHTML = htmlString
            }
            
            
            
            
            // for-loop
            function viewJSONData()
            {
                let htmlString = `<ul>`
                for(let round = 0; round < countryQuizData.rounds.length; round++)
                {
                    htmlString += `<li>${countryQuizData.rounds[round].name}</li>`
                    htmlString += `<ul>`
                    for(let question = 0; question < countryQuizData.rounds[round].questions.length; question++)
                    {
                        htmlString += `<li>${countryQuizData.rounds[round].questions[question].text}</li>
                                       <ul>`
                        for(let choice = 0; choice < countryQuizData.rounds[round].questions[question].choices.length; choice++)
                        {
                            if(choice === countryQuizData.rounds[round].questions[question].correct)
                            {
                                htmlString += `<span style='color:redfont-weight:bold'>`
                            }
                            htmlString += `<li>${countryQuizData.rounds[round].questions[question].choices[choice]}</li>` 
                            if(choice === countryQuizData.rounds[round].questions[question].correct)
                            {
                                htmlString += `</span>`
                            }
                        }
                        htmlString += `</ul>`
                    }
                    htmlString += `</ul>`
                }
                htmlString += `</ul>`
                document.getElementById("quiz").innerHTML = htmlString
            }

Advanced Nested JSON

Once we know how to access the data at the different levels of a nested JSON object, we can write more complicated code, such as in the questions below:

Adjust the code above to show all of the questions and possible answers in the quiz. The correct answer should be highlighted for each question, as shown here. Hint: You need to use the map() method's optional index parameter. In your code, you can identify if the answer is correct by comparing map()'s index against the question's correct property value.

Write code to allow a user to answer each of the questions in the quiz. The user should be given their score when they finish the quiz, as shown here.

Tabular Data

Tabular data can be stored as two arrays inside a JSON object. One array will hold the property keys (table column headings) and the second array can hold the property values (table rows data). For example, consider the tablular data below:

CountryCapitalPopulation
IrelandDublin5000000
FranceParis65000000
PolandWarsaw38000000

Using key/value pairs, we can store this data in the JSON object below:

countryData = [
                  {
                      name: "Ireland",
                      capital: "Dublin",
                      population: 5000000 
                  },                            
                  {
                      name: "France",
                      capital: "Paris",
                      population: 65000000 
                  },
                  {
                      name: "Poland",
                      capital: "Warsaw",
                      population: 38000000  
                  }
              ]

Because it is tabular, we can also store this data in a JSON object that has two arrays, one each for the keys and values, as shown below:

countryData = {
                keys: ["Name", "Capital City","Population"], 
                values: 
                      [
                          ["Ireland", "Dublin", 5000000],
                          ["France", "Paris", 65000000],
                          ["Poland", "Warsaw", 38000000]
                      ]
              }

The keys array and and each of the values arrays MUST have the same number of elements (in the above case, three elements).

The tabular data arrays do not always have to be called keys and values. They can be any names that are appropriate for the given data.

 

To access a specific key/value pair from the JSON data above, we assign a constant to identify the index of each key/value

countryData = {
                keys: ["Name", "Capital City","Population"], 
                values: 
                      [
                          ["Ireland", "Dublin", 5000000],
                          ["France", "Paris", 65000000],
                          ["Poland", "Warsaw", 38000000]
                      ]
              }

const NAME = 0,
      CAPITAL = 1,
      POPULATION = 2

The code below allows us to access the three keys

countryData.keys[NAME]
countryData.keys[CAPITAL]
countryData.keys[POPULATION]

The code below allows us to access the three values of the first country (which has index 0)

countryData.values[0][NAME]     
countryData.values[0][CAPITAL]      
countryData.values[0][POPULATION]

 

Normally, we would loop through the values to produce some kind of tabular output. The example below shows how we do this.

Example of tabular data being held in a JSON object (Run Example)

<!DOCTYPE html>
<html>
<head>
<title>JSON Tabular data example</title>

<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="Content-Language" content="en" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<style>
#countriesTable
{
    width:250px;
    margin-left:auto;
    margin-right:auto;
    border-collapse:collapse;
}

#countriesTable th
{
    text-align: left;
    background-color:#aaa;
    color:#fff;
}

#countriesTable th,
#countriesTable td
{
    padding:5px;
}

#countriesTable .population
{
    text-align:right;
}

#countriesTable tbody
{
    border:thin solid #aaa;
}

#countriesTable tbody tr:nth-child(odd)
{
    background-color: #ffa;
}

.right_align
{
    text-align: right !important;
}
</style>

<script>
function showCountriesTable()
{
    countryData = {
        keys: ["Name", "Capital City","Population"], 
        values: 
            [
                ["Ireland", "Dublin", 5000000],
                ["France", "Paris", 65000000],
                ["Poland", "Warsaw", 38000000]
            ]
    }
    
    const NAME = 0,
          CAPITAL = 1,
          POPULATION = 2    

    let innerHTML = `<table id="countriesTable">
                         <tr>
                             <th>${countryData.keys[NAME]}</th>
                             <th>${countryData.keys[CAPITAL]}</th>
                             <th class="right_align">${countryData.keys[POPULATION]}</th>
                         </tr>`           
        
    countryData.values.map(country => innerHTML += `<tr>
                                                        <td>${country[NAME]}</td>
                                                        <td>${country[CAPITAL]}</td>
                                                        <td class="right_align">${country[POPULATION]}</td>
                                                    </tr>`)
        
    innerHTML += `</table>`
    document.getElementById("countries").innerHTML = innerHTML
}
</script>
</head>

<body onload='showCountriesTable()'>
<div id='countries'></div>
</body>
</html>

 

We can hold both key/value data and tabular array data in the same JSON object. In the example below, modules and moduleGrades hold the tabular data keys and values arrays, while name and id hold normal key/value data.

In this example, the modules array and each of the moduleGrades arrays hold three elements.

studentsData = {
                modules: ["Programming", "Mathematics", "Web"], 
                students:
                        [
                            {
                                name: "Colm",
                                id: 3333,
                                moduleGrades: [65, 45, 70]  
                            },
                            {
                                name: "Grace",
                                id: 6666,
                                moduleGrades: [37, 39, 44]  
                            },
                            {
                                name: "Deirdre",
                                id: 4444,
                                moduleGrades: [80, 85, 82]  
                            },
                            {
                                name: "Brian",
                                id: 2222,
                                moduleGrades: [30, 45, 40]  
                            },
                            {
                                name: "Francis",
                                id: 5555,
                                moduleGrades: [40, 50, 44]  
                            },
                            {
                                name: "Anne",
                                id: 1111,
                                moduleGrades: [70, 85, 90]  
                            }
                        ]
            }

Given the JSON data above, write code (as shown here) to allow a user to:



Write code to improve the visual user-interface of the above example.

JSON Array Search

The filter() method can be used to search for one or more elements in an JSON array.

The code below will return an JSON array that contains all of the cars that match the search colour.

function searchCarsByColour(colour)
{
    const selectedCars = cars.filter(car => car.colour === colour)
    return selectedCars
}


// Example
let selectedCars = searchCarsByColour("Red")

The code below will return the one element that matches the search id

function searchCarsByID(id)
{
    const selectedCars = cars.filter(car => car.id === id)
    return selectedCars[0]
}


// Example
let selectedCar = searchCarsByID(4)

The filter() method returns an array. However, as we are searching aginast a unique id, we know that there will only be a match for one element. Therefore, the first element in the selectedCars array - selectedCars[0] - will contain the one matched element.

Add Element to JSON Array

Use the push() method to add an element to any array. The code below will add a new car JSON object to a cars JSON array.

function addCar(model, colour, year, price)
{
    let newCar = {model:model, colour:colour, year:year, price:price}
    cars.push(newCar)
}



// Example
addCar("Avensis", "Red", 2020, 15000)

We often need to include a unique id for each element in a JSON array. The code below will add a car with a unique id to a JSON array of cars.

function addCar(model, colour, year, price)
{
    let newCar = {id:uniqueId, model:model, colour:colour, year:year, price:price}
    cars.push(newCar)
    
    uniqueId++  
}



// Example
addCar("Avensis", "Red", 2020, 15000)

Assuming that uniqueId was unique before calling the function, we use the uniqeId for this element and then increment uniqueId, so that it will be a new unique number the next time we go to add another new element.

Modify JSON Array Element

In order to modify an element, we need to be able identify that element. We can use the element's id to do this.

We can use the map() method to step through all of the elements in the array. Inside the map(), we can use an if statement to match against the element that we want to modify. We can then replace this elements details with the new, modified, details.

function modifyCar(id, model, colour, year, price)
{
    cars.map(car => 
    {
        if(car.id === id)
        {
            car.model = model    
            car.colour = colour
            car.year = year
            car.price = price
        }
    })            
}



// Example
updateCar(4, "Corolla", "Silver", 2020, 10000)

Delete JSON Array Element

In order to delete an element, we need to be able identify that element. We can use the element's id to do this.

We can use the map() method to step through all of the elements in the array. Inside the map(), we can use an if statement to match against the element that we want to delete. Within the if statement can note the index in the array of the element that we want to delete. We shall store this index in selectedIndex. Finally, we use the splice() method to delete the selectedIndex element from the array

function deleteCar(id)
{
    let selectedIndex
    cars.map((car, index) => 
    {
        if(car._id === id)
        {
            selectedIndex = index
        }
    })

    cars.splice(selectedIndex, 1)
} 



// Example
deleteCar(4)

The second parameter in the splice() method is the number of elements that we want to delete. In this case, we want to delete 1 element.

Write code to allow a user to search by id, search by model, add, modify and delete cars from a JSON array, as shown here.

 
<div align="center"><a href="../versionC/index.html" title="DKIT Lecture notes homepage for Derek O&#39; Reilly, Dundalk Institute of Technology (DKIT), Dundalk, County Louth, Ireland. Copyright Derek O&#39; Reilly, DKIT." target="_parent" style='font-size:0;color:white;background-color:white'>&nbsp;</a></div>