I am wondering how would I get the next JSON item if I have the key in JavaScript. For example, if I provide the key 'Josh' how would I get the contents of 'Annie' along with the key 'Annie'? Would I have to process the JSON in an array and extract from there?
In addition, I believe that there is a proper term for transforming data from one type to another. Any chance anyone knows what it is... it is just on the tip of my tongue!
{
"friends": {
"Charlie": {
"gender": "female",
"age": "28"
},
"Josh": {
"gender": "male",
"age": "22"
},
"Annie": {
"gender": "female",
"age": "24"
}
}
}
In JavaScript the order of Object properties is not guaranteed (ECMAScript Third Edition (pdf):)
4.3.3 Object An object is a member of the type Object. It is an unordered collection of properties each of which contains a primitive
value, object, or function. A function stored in a property of an
object is called a method.
If the order doesn't have to be guaranteed you could do the following:
var t = {
"friends": {
"Charlie": {
"gender": "female",
"age": "28"
},
"Josh": {
"gender": "male",
"age": "22"
},
"Annie": {
"gender": "female",
"age": "24"
}
}
};
// Get all the keys in the object
var keys = Object.keys(t.friends);
// Get the index of the key Josh
var index = keys.indexOf("Josh");
// Get the details of the next person
var nextPersonName = keys[index+1];
var nextPerson = t.friends[nextPersonName];
If order matters I would recommend having another array of to hold the order of the names ["Charlie", "Josh", "Annie"] instead of using Object.keys().
var t = ...;
// Hard code value of keys to make sure the order says the same
var keys = ["Charlie", "Josh", "Annie"];
// Get the index of the key Josh
var index = keys.indexOf("Josh");
// Get the details of the next person
var nextPersonName = keys[index+1];
var nextPerson = t.friends[nextPersonName];
Related
I am currently working on a website that imports JSON data and populates a table within HTML. In this instance the JSON file has already been parsed and exists as an JavaScript object.
I am having trouble iterating through the arrays within the object to try and add data with different key values to a single table row.
what I want to achieve is to have the names of each employee who works in a particular department to be present in a single row.
I started by creating an empty array outside my for loops.
I have iterated through the object using three separate for loops and appended the names of the employees to this empty array. After my loops i have let my now full array that contains the names equal to an empty array.
What i have been working on can be seen here https://jsfiddle.net/kn0y9g5d/
<div id="id01"></div>
<script>
const table =
{ "Employees":
[ { "Started" : "2016"
, "Department": "Engineering"
, "Employee":
[ { "id": "a101", "firstname": "Alan", "surname": "Arkin" }
, { "id": "a102", "firstname": "Geoff", "surname": "keegan" }
]
}
, { "Started" : "2016"
, "Department": "R&D"
, "Employee":
[ { "id": "a103", "firstname": "Michele", "surname": "Jones" }
, { "id": "a104", "firstname": "Peter", "surname": "Smith" }
]
}
]
}
var DepName =[];
var employeeNames =[];
let MyTable = document
.querySelector('#id01')
.appendChild(document.createElement('table'))
for (let StartDep of table.Employees)
{
for (let Employee of StartDep.Employee )
{
for (let Employee1 of StartDep.Employee ){
var name = Employee1.firstname + " " + Employee1.surname
employeeNames.push(name)
let nRow = MyTable.insertRow(-1)
, rCell = 0
nRow.insertCell(rCell++).textContent = StartDep.Started
nRow.insertCell(rCell++).textContent = StartDep.Department
nRow.insertCell(rCell++).textContent = employeeNames
}employeeNames=[];
}
}
let Rowhead = MyTable.createTHead().insertRow(-1)
'Started,Department,Name(s)'.split(',')
.forEach((T,i)=>Rowhead.insertCell(i).textContent=T)
</script>
what I expect to get using this code will be similar to this https://i.stack.imgur.com/Vgvlo.png
console.log(table);
const abc = [];
for(var j=0;j<2;j++)
{
const gh = [];
for(var i =0;i<2;i++)
{
let name = table.Employees[j].Employee[i].firstname+" "+table.Employees[j].Employee[i].surname
gh.push(name);
}
var totalName = gh.join();
abc.push(totalName);
}
console.log(table.Employees[0].Employee[0].firstname);
console.log(abc);
if you do this before appending this to table you should be able to get the result easily
i did it on my own so i cant give you any reference to look at.
hope this helps
I'm trying to create a function that when called will update a specific object in json file. However, it updates the object as well as creating a new one.
I've tried many different methods in trying to get this to work, but all have failed. The closest I've got to it working is the code shown below, but it still doesn't do what is required.
This is my function:
var fs = require('fs');
var _ = require("underscore");
module.exports = {
personalUpdate: function (id, forename, surname, dob, gender, callback) {
let rawdata = fs.readFileSync('data.json');
let data = JSON.parse(rawdata);
let filtered = _.where(data['students'], { id: id });
let all = filtered[0];
all.forename = forename;
all.surname = surname;
all.dob = dob;
all.gender = gender;
data["students"].push(all);
fs.writeFileSync('data.json', JSON.stringify(data, null, 2), (err) => {
if (err) throw err;
});
callback("success");
}
}
And this is the JSON file that I want to update:
{
"teachers": [
{
"name": "",
"email": "",
"password": "",
"formGroup": "",
"id": ""
}
],
"students": [
{
"surname": "test",
"forename": "test",
"dob": "",
"homeAddress": "",
"homePhone": "",
"gender": "",
"tutorGroup": "",
"schoolEmail": "",
"grades": [
{
"french": 8,
"maths": 7
}
],
"id": ""
},
{
"surname": "test2",
"forename": "test2",
"dob": "",
"homeAddress": "test2",
"homePhone": "",
"gender": "",
"tutorGroup": "",
"schoolEmail": "",
"grades": [
{
"french": 9,
"maths": 8
}
],
"id": ""
}
]
}
I had to remove and change the objects and info inside them, as it contained confidential information.
When running this function, it finds the object that is specified in the parameter. It then updates that object, but it then creates another object at the bottom of the original JSON object, which it is not supposed to.
Also, is there a better way to update the specific objects in the JSON file?
tl;dr
The result set is duplicating because you are pushing it into the array
The change is being applied due to the variables holding the same object reference, so they are being mirrored across objects that share the same pointer.
Explanation
It creates a new one due to the data["students"].push(all); instruction.
When you manipulate objects in javascript you need to be aware of how the reference between them work, so you can avoid bugs and use them in your benefit.
For example, take this set of instructions:
let a = {"x": 1};
let b = a;
b.x = 3;
console.log(a) // it will output {"x": 3}
Notice that we:
Create an object with the prop x equal 1 and assign it to the variable a
Initialize a variable b with the value of a
Change the property x on the variable/object b
Then we can observe that the change was also reflected in the variable a, due to the object reference.
So, basically this is exactly what is happening with your instructions when you do all.forename = forename; it changes the variable all, but also the original object which it derives from.
Here is a nice reference that explains this concept more in-depth
#EDIT
I strongly advise you not using the sync version of functions like readFileSync since this blocks the event loop. Here is the official guidelines about it
here i state with data
state = {
Response: [
{
"id": "15071",
"name": "John",
"salary": "53",
"age": "23",
"department": "admin"
},
{
"id": "15072",
"name": "maxr",
"salary": "53",
"age": "23",
"department": "admin"
},
{
"id": "15073",
"name": "Josef",
"salary": "53",
"age": "23",
"department": "admin"
},
{
"id": "15074",
"name": "Ye",
"salary": "53",
"age": "23",
"department": "admin"
}
]
i am displaying these records in the table. In table u will see 10 records and there will be a button on top of table so if append button is pressed then 10 records has to be added on every button press and the data has to be same but it has to be appended using the below logic i am trying to set the state by pushing 10 records and trying to append it for ex if i have 1,2,3,4,5,6,7,8,9,10 if i press append 1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10 has to be apeended
appendEmployees() {
var reLoadCount = 1;
for (let i = 0; i < 10; i++) {
const myObj = {
id: 0,
name: '',
salary: 0,
department: ''
};
myObj.id = +this.setState.employee[i].id + (reLoadCount * 10);
myObj.name = this.setState.employee[i].name;
myObj.salary = this.setState.employee[i].salary;
myObj.department = this.setState.employee[i].department;
this.setState.employee.push(myObj);
}
reLoadCount++;
}
am i doing some thing wrong here
If I get this right you're trying to add 10 duplicates of the objects in the this.state.employee array, the only difference between these new objects and the existing ones is their id.
If that is the case, here is how you can do that:
appendEmployees() {
this.setState(prevState => {
// Get the biggest ID number.
const maxId = Math.max(...prevState.employee.map(e => parseInt(e.id)));
// create 10 new employees copies of the first 10.
const newEmployees = prevState.employee.slice(0, 10).map((e, i) => ({
...e,
id: (maxId + i + 1)
}));
// return/update the state with a new array for "employee" that is a concatenation of the old array and the array of the 10 new ones.
return {
employee: [...prevState.employee, ...newEmployees]
}
});
}
I've added some comments to the example to explain what it does.
The important thing is this.setState which is the function used to update the state, here, I've used it with a function as the first parameter (it works with objects as well), I've did that because it is the preferred way of generating a new state that is derived from the old state.
Is there any way to parse/filter the data present in JSON file in a Javascript file.
Basically, I am calling JSON file into my local javascript. I am having trouble in reading specific data and printing.
Can anyone please help.
JSON file contains:
{
"Data": [
{
"name": "John",
"age": 30
},
{
"joined on":"Jan 2015",
"working on": "Automation",
}
]
}
I am trying to read the above JSON file as:
var jfile = require("./Example.json");
var test = JSON.parse(JSON.stringify(jfile))
console.log(test)
I get the output like this:
{ Data:
[ { name: 'John', age: 30 },
{ 'joined on': 'Jan 2015', 'working on': 'Automation' } ] }
From the above, I am interested in accessing/filtering out only one i.e. "name". I would like to print only the value "John" to the console.
I have tried to use the ".filter" method to the JSON.parse method but it throws me an error as:
JSON.parse(...).filter is not a function
Is there any way to perform this activity?
You can access it using . dot notation
var a = {
"Data": [{
"name": "John",
"age": 30
},
{
"joined on": "Jan 2015",
"working on": "Automation",
}
]
}
console.log(a.Data[0].name)
filter is an array method.
JSON.parse(...) will not give you an array. It will give you an object with a Data property. The value of that property is an array.
JSON.parse(...).Data.filter.
You can't just ignore parts of your data structure.
If you have multiple items in your array of different shapes, you can use this
Access the Data key with json.Data
map your array to transform its items into names
apply filter(Boolean) to take out those who are undefined
In your case you'll end up with an array containing only one name John
const getName = json => json.Data.map(x => x.name).filter(Boolean);
const json = {
"Data": [{
"name": "John",
"age": 30
},
{
"joined on": "Jan 2015",
"working on": "Automation",
}
]
};
console.log(getName(json));
Your JSON's main level is an object (not an array) and only arrays have .filter method.
So filter the array under Data key:
var test = JSON.parse(JSON.stringify(jfile)).Data.filter(/*something*/);
But better if you aren't re-parse JSON:
var test = jfile.Data.filter(/*something*/);
As Quentin mentioned in his comment, What is the use of below statement ?
var test = JSON.parse(JSON.stringify(jfile))
You can directly access the name property from the response.
Try this :
var obj = {
"Data": [{
"name": "John",
"age": 30
},
{
"joined on": "Jan 2015",
"working on": "Automation"
}
]
};
// Solution 1
console.log(obj.Data.map(item => item.name).filter(Boolean));
// Solution 2
console.log(obj.Data.filter(item => item.name).map(elem => elem.name));
Not quite grasping what's going on here. Given the array (arr):
[
{
"first_name": "Dan",
"last_name": "Woodson",
"id": 1
},
{
"first_name": "Jen",
"last_name": "Woodson",
"id": 2
},
{
"first_name": "Yoshi",
"last_name": "Woodson",
"id": 3
}
]
And the object (obj):
{
"first_name": "Yoshi",
"last_name": "Woodson",
"id": 3
}
Why would arr.indexOf(obj) return -1 (especially since I retrieved the object from the array using it's 'id' parameter earlier in the function)?
Array.indexOf() will only work on objects if the supplied object is exactly the same object you put in.
An exact copy is insufficient, it has to be the exact same object, i.e. there must be some object in the array such that:
arr[i] === obj
You need to show how you retrieved the object.
I would like to see the retrieve function, but most likely you are not using the same reference. Because the following is true:
var a = {id: 3};
var b = [a];
b.indexOf(a); // 0
a.id = "not three";
b.indexOf(a); // still 0
However, the following will break:
var a = {id: 3};
var b = [{id: 3}];
b.indexOf(a); // -1 not the same object