JavaScript array comparison with JSON response - javascript

I have this project I'm working on and I need to get all the vacant rooms from my school's timetable where I get my data from a JSON response.
The JSON response looks like this:
{
"status": "success",
"reservations": [
{
"id": "19598",
"subject": "subjectName",
"modifiedDate": "2017-04-24T06:04:42",
"startDate": "2017-04-24T08:00:00",
"endDate": "2017-04-24T09:45:00",
"resources": [
{
"id": "795",
"type": "student_group",
"code": "groupCode",
"name": "groupName"
},
{
"id": "599",
"type": "student_group",
"code": "groupCode",
"name": "groupName"
},
{
"id": "2989",
"type": "realization",
"code": "",
"name": ""
},
{
"id": "41",
"type": "room",
"code": "A340.1",
"parent": {
"id": "2",
"type": "building",
"code": "A",
"name": "buildingA"
},
"name": "A340.1"
}
],
"description": ""
},
{
"id": "27832",
"subject": "subjectName",
"modifiedDate": "2017-04-24T06:04:42",
"startDate": "2017-04-24T08:00:00",
"endDate": "2017-04-24T09:45:00",
"resources": [
{
"id": "52",
"type": "room",
"code": "A450.3",
"parent": {
"id": "2",
"type": "building",
"code": "A",
"name": "buildingA"
},
"name": "A450.3"
},
{
"id": "2409",
"type": "student_group",
"code": "groupCode",
"name": "groupName"
},
{
"id": "3401",
"type": "realization",
"code": "",
"name": ""
}
],
""
},
{
"id": "10945",
"subject": "subjectName",
"modifiedDate": "2017-04-24T06:04:43",
"startDate": "2017-04-24T08:00:00",
"endDate": "2017-04-24T12:00:00",
"resources": [
{
"id": "289",
"type": "student_group",
"code": "groupCode",
"name": "gorupName"
},
{
"id": "2454",
"type": "realization",
"code": "",
"name": ""
},
{
"id": "19",
"type": "room",
"code": "A510.4",
"parent": {
"id": "2",
"type": "building",
"code": "A",
"name": "buildingA"
},
"name": "A510.4"
}
],
"description": ""
},
{
"id": "27647",
"subject": "subjectName",
"modifiedDate": "2017-04-24T06:04:39",
"startDate": "2017-04-24T08:00:00",
"endDate": "2017-04-24T21:00:00",
"resources": [
{
"id": "47",
"type": "room",
"code": "A420.6",
"parent": {
"id": "2",
"type": "building",
"code": "A",
"name": "buildingA"
},
"name": "A420.6"
}
],
"description": ""
},
{
"id": "20630",
"subject": "subjectName",
"modifiedDate": "2017-04-24T06:04:33",
"startDate": "2017-04-24T08:00:00",
"endDate": "2017-04-24T10:45:00",
"resources": [
{
"id": "25",
"type": "room",
"code": "A130.1",
"parent": {
"id": "2",
"type": "building",
"code": "A",
"name": "buildingA"
},
"name": "A130.1"
},
{
"id": "26",
"type": "room",
"code": "A130.3",
"parent": {
"id": "2",
"type": "building",
"code": "A",
"name": "buildingA"
},
"name": "A130.3"
},
{
"id": "2997",
"type": "realization",
"code": "",
"name": ""
},
{
"id": "2268",
"type": "student_group",
"code": "groupCode",
"name": "gorupName"
}
],
"description": ""
},
{
"id": "19874",
"subject": "subjectName",
"modifiedDate": "2017-04-24T06:04:37",
"startDate": "2017-04-24T08:00:00",
"endDate": "2017-04-24T09:45:00",
"resources": [
{
"id": "28",
"type": "room",
"code": "A140.2",
"parent": {
"id": "2",
"type": "building",
"code": "A",
"name": "buildingA"
},
"name": "140.2"
},
{
"id": "3033",
"type": "realization",
"code": "",
"name": ""
},
{
"id": "2338",
"type": "student_group",
"code": "groupCode",
"name": "groupname"
}
],
"description": ""
}
]
}
The response is a lot longer but I've kept it shorter for simplicity's sake.
So I've run this JSON response through with JSON.Parse() and for-loops to get all the rooms that all currently in use in an array;
var rooms = [];
for (var i = 0; i < json.reservations.length; i++) {
if(json.reservations[i].resources != null){
for(var j = 0; j < json.reservations[i].resources.length; j++){
var resource = json.reservations[i].resources[j];
if(resource.type === "room"){
if(rooms.indexOf("code"))
rooms.push(resource.code);
}
}
}
}
}
I get all the rooms that are being used at the time as you can see from the response above for example;
"startDate": "2017-04-24T08:00:00",
"endDate": "2017-04-24T09:45:00",
"type": "room",
"code": "A340.1",
But the problem is that the API that I'm using doesn't contain any data for the vacant rooms at the moment so I also made an array for all the rooms in the buildingA which looks like this:
var buildingA = ['A120.3', 'A130.1', 'A130.3', 'A140.1', 'A140.2', 'A140.4', 'A250.1', 'A240.4', 'A240.2', 'A220.5', 'A220.3',
'A220.1', 'A210.2', 'A320.2', 'A320.6', 'A320.7', 'A320.8', 'A340.1', 'A340.2', 'A350.1', 'A350.3', 'A440.5', 'A450.3',
'A450.1', 'A440.4', 'A440.2', 'A420.6', 'A420.5', 'A420.4', 'A420.2', 'A510.2', 'A520.5', 'A510.4', 'A520.6', 'A520.7',
'A540.1', 'A540.2'];
Is there any way I could compare this array to the var rooms = []; array so I could print all the vacant rooms instead of the ones being in use?
As for the results I would have to see the name of the vacant room and the time how long it stays vacant (if possible) but the main thing would be to get the room name for example;
A340.1 - 1 hour 45 minutes
A440.4 - 2 hours
Thanks in advance.

Basically, you could collect first the rooms which are booked and then get either completely free rooms or render free times.
var data = { status: "success", reservations: [{ id: "19598", subject: "subjectName", modifiedDate: "2017-04-24T06:04:42", startDate: "2017-04-24T08:00:00", endDate: "2017-04-24T09:45:00", resources: [{ id: "795", type: "student_group", code: "groupCode", name: "groupName" }, { id: "599", type: "student_group", code: "groupCode", name: "groupName" }, { id: "2989", type: "realization", code: "", name: "" }, { id: "41", type: "room", code: "A340.1", parent: { id: "2", type: "building", code: "A", name: "buildingA" }, name: "A340.1" }], description: "" }, { id: "27832", subject: "subjectName", modifiedDate: "2017-04-24T06:04:42", startDate: "2017-04-24T08:00:00", endDate: "2017-04-24T09:45:00", resources: [{ id: "52", type: "room", code: "A450.3", parent: { id: "2", type: "building", code: "A", name: "buildingA" }, name: "A450.3" }, { id: "2409", type: "student_group", code: "groupCode", name: "groupName" }, { id: "3401", type: "realization", code: "", name: "" }], description: "" }, { id: "10945", subject: "subjectName", modifiedDate: "2017-04-24T06:04:43", startDate: "2017-04-24T08:00:00", endDate: "2017-04-24T12:00:00", resources: [{ id: "289", type: "student_group", code: "groupCode", name: "gorupName" }, { id: "2454", type: "realization", code: "", name: "" }, { id: "19", type: "room", code: "A510.4", parent: { id: "2", type: "building", code: "A", name: "buildingA" }, name: "A510.4" }], description: "" }, { id: "27647", subject: "subjectName", modifiedDate: "2017-04-24T06:04:39", startDate: "2017-04-24T08:00:00", endDate: "2017-04-24T21:00:00", resources: [{ id: "47", type: "room", code: "A420.6", parent: { id: "2", type: "building", code: "A", name: "buildingA" }, name: "A420.6" }], description: "" }, { id: "20630", subject: "subjectName", modifiedDate: "2017-04-24T06:04:33", startDate: "2017-04-24T08:00:00", endDate: "2017-04-24T10:45:00", resources: [{ id: "25", type: "room", code: "A130.1", parent: { id: "2", type: "building", code: "A", name: "buildingA" }, name: "A130.1" }, { id: "26", type: "room", code: "A130.3", parent: { id: "2", type: "building", code: "A", name: "buildingA" }, name: "A130.3" }, { id: "2997", type: "realization", code: "", name: "" }, { id: "2268", type: "student_group", code: "groupCode", name: "gorupName" }], description: "" }, { id: "19874", subject: "subjectName", modifiedDate: "2017-04-24T06:04:37", startDate: "2017-04-24T08:00:00", endDate: "2017-04-24T09:45:00", resources: [{ id: "28", type: "room", code: "A140.2", parent: { id: "2", type: "building", code: "A", name: "buildingA" }, name: "140.2" }, { id: "3033", type: "realization", code: "", name: "" }, { id: "2338", type: "student_group", code: "groupCode", name: "groupname" }], description: "" }] },
rooms = ['A120.3', 'A130.1', 'A130.3', 'A140.1', 'A140.2', 'A140.4', 'A250.1', 'A240.4', 'A240.2', 'A220.5', 'A220.3', 'A220.1', 'A210.2', 'A320.2', 'A320.6', 'A320.7', 'A320.8', 'A340.1', 'A340.2', 'A350.1', 'A350.3', 'A440.5', 'A450.3', 'A450.1', 'A440.4', 'A440.2', 'A420.6', 'A420.5', 'A420.4', 'A420.2', 'A510.2', 'A520.5', 'A510.4', 'A520.6', 'A520.7', 'A540.1', 'A540.2'],
booking = Object.create(null),
free;
data.reservations.forEach(function (reservation) {
reservation.resources.some(function (resource) {
if (resource.type === 'room') {
booking[resource.code] = booking[resource.code] || [];
booking[resource.code].push({ startDate: reservation.startDate, endDate: reservation.endDate });
return true;
}
});
});
free = rooms.filter(function (a) {
return !booking[a];
});
console.log(booking);
console.log(free);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Hope the below helps in filtering the array.
var vacantRooms = buildingA.filter((x) => {return !rooms.find((y) => {return y == x})});

Related

sequelize aggregate function gives wrong result

I'm newbie and sequelize aggregate function makes me confused because it gave me different result than expected. I'm trying to get a total price with sequelize.fn('sum', ...), and somehow sequelize only gives me the the total of first data of the associated model instead of summing all the result. My code as follows:
Training.findAll({
where: {
owner_id: payload
},
attributes: ['id', [sequelize.fn('sum', sequelize.col('training_classes.price')), 'totalPrice']],
include: [{
model: TrainingClass,
as: 'training_classes',
attributes: ['id', 'price'],
}],
group: ['Training.id', 'training_classes.id']
})
And the result of the query :
[
{
"id": "45",
"totalPrice": "300000",
"training_classes": [
{
"id": "94",
"price": "300000"
}
]
},
{
"id": "8",
"totalPrice": "1000000",
"training_classes": [
{
"id": "14",
"price": "1000000"
},
{
"id": "15",
"price": "300000"
},
{
"id": "16",
"price": "200000"
}
]
},
{
"id": "47",
"totalPrice": "100000",
"training_classes": [
{
"id": "97",
"price": "100000"
}
]
},
{
"id": "39",
"totalPrice": "1000000",
"training_classes": [
{
"id": "81",
"price": "1000000"
},
{
"id": "82",
"price": "300000"
}
]
},
{
"id": "24",
"totalPrice": "300000",
"training_classes": [
{
"id": "46",
"price": "300000"
}
]
},
{
"id": "6",
"totalPrice": "200000",
"training_classes": [
{
"id": "11",
"price": "200000"
}
]
},
{
"id": "49",
"totalPrice": "100000",
"training_classes": [
{
"id": "100",
"price": "100000"
},
{
"id": "99",
"price": "1000000"
},
{
"id": "101",
"price": "100000"
}
]
},
{
"id": "20",
"totalPrice": "200000",
"training_classes": [
{
"id": "38",
"price": "200000"
},
{
"id": "35",
"price": "400000"
},
{
"id": "37",
"price": "500000"
},
{
"id": "36",
"price": "100000"
}
]
},
]
as you can see, the totalPrice only from the first element of training_classes, not the entire data of it. How can I resolve this? Thank you in advance
If you want to sum all records in TrainingClass that have the same Training.id then you need to indicate no attributes for TrainingClass and indicate only Training.id in group option:
Training.findAll({
where: {
owner_id: payload
},
attributes: ['id', [sequelize.fn('sum', sequelize.col('training_classes.price')), 'totalPrice']],
include: [{
model: TrainingClass,
as: 'training_classes',
attributes: [],
}],
group: ['Training.id']
})
If you group by TrainingClass.id then you'll get grouped results for each record that has unique TrainingClass.id value and literally every record of TrainingClass has unique id value.

Objects data to be updated with value from Array

I'm trying to update the 'positionTitle' field of my graphData object with the 'positionTitle fields of my individualData array.
I need to do it accurately, both sets of data have 'accounts' which both have the same id and fullname for user, I was hoping to try and use this to do the matching.
I want the positionTitle's from the users with same account id or name (whichever is easier) to go into the objects fields.
This is currently what I have:
My Object (that i want to update):
graphData = {
"name": "Annual meetings",
"engagementAreas": [{
"id": "1",
"engagementTypes": [{
"name": "forestry",
"engagements": []
},
{
"name": "houses",
"engagements": [{
"name": "engagement1",
"members": [{
"id": "e334", "account": {
"id": "eefe", "fullName": "jim bean"
},
"position": {
"id": "3434",
"positionTitle": "Manager"
}
}]
}]
},
{
"name": "landscaping",
"engagements": [{
"name": "engagement1343",
"members": [{
"id": "e334", "account": {
"id": "123", "fullName": "john boer"
},
"position": {
"id": "4545",
"positionTitle": "Senior Manager"
}
}]
}]
}
]
},
{
"name": "community days",
"engagementTypes": [{
"name": "skyscraping",
"engagements": []
},
{
"name": "tennis",
"engagements": [{
"name": "engagement346",
"members": [{
"id": "34", "account": {
"id": "0010X000048DDMsQAO", "fullName": "edy long"
},
"position": {
"id": "3999434",
"positionTitle": "Ultime Manager"
}
}]
}]
},
{
"name": "Juicing",
"engagements": [{
"name": "347343",
"members": [{
"id": "4546", "account": {
"id": "001b000003WnPy1AAF", "fullName": "jeff bint"
},
"position": {
"id": "35006",
"positionTitle": "Senior Ultimate Manager"
}
}]
}]
}]
}]
}
My array whose positionTitles I want to take:
IndividualData = [{
"account": {
"id": "001b000003WnPy1AAF",
"fullName": "jeff bint"
},
"positions": [{
"id": "a16b0000004AxeBAAS",
"organizationId": "001b0000005gxmlAAA",
"organizationName": "a",
"positionTitle": "Senior Manager, Energy",
"positionLevel": "5-Middle Management & Advisers",
"isPrimary": true,
"startDate": "2016-10-07",
"endDate": null
}]
}, {
"account": {
"id": "0010X000048DDMsQAO",
"fullName": "edy long"
},
"positions": [{
"id": "a160X000004nKfhQAE",
"organizationId": "001b0000005gxmlAAA",
"organizationName": "a",
"positionTitle": "Managing Director",
"positionLevel": "4-Head of Business Unit/Head of Region",
"isPrimary": true,
"startDate": "2018-03-05",
"endDate": null
}]
}, {
"account": {
"id": "123",
"fullName": "john boer"
},
"positions": [{
"id": "325345634634",
"organizationId": "001b0000005gxmlAAA",
"organizationName": "a",
"positionTitle": "Managing Director",
"positionLevel": "4-Head of Business Unit/Head of Region",
"isPrimary": true,
"startDate": "2018-03-05",
"endDate": null
}]
}
]
The function I'm currently using, which does take the first positiontitle field of the array:
const updatedGraphTable = { ...graphData,
engagementAreas: graphData.engagementAreas.map(area => ({ ...area,
engagementTypes: area.engagementTypes.map(type => ({ ...type,
engagements: type.engagements.map(engagement => ({ ...engagement,
members: engagement.members.map(member => ({ ...member,
position: { ...member.position,
positionTitle: IndividualData[0].positions[0].positionTitle
}
}))
}))}))
}))
};
console.log(updatedGraphTable)
console.log('a' + JSON.stringify(updatedGraphTable))
my expected result with the positions updated:
updatedGraphData = {
"name": "Annual meetings",
"engagementAreas": [{
"id": "1",
"engagementTypes": [{
"name": "forestry",
"engagements": []
},
{
"name": "houses",
"engagements": [{
"name": "engagement1",
"members": [{
"id": "e334", "account": {
"id": "eefe", "fullName": "jim bean"
},
"position": {
"id": "3434",
"positionTitle": "Manager"
}
}]
}]
},
{
"name": "landscaping",
"engagements": [{
"name": "engagement1343",
"members": [{
"id": "e334", "account": {
"id": "123", "fullName": "john boer"
},
"position": {
"id": "4545",
"positionTitle": "Managing Director"
}
}]
}]
}
]
},
{
"name": "community days",
"engagementTypes": [{
"name": "skyscraping",
"engagements": []
},
{
"name": "tennis",
"engagements": [{
"name": "engagement346",
"members": [{
"id": "34", "account": {
"id": "0010X000048DDMsQAO", "fullName": "edy long"
},
"position": {
"id": "3999434",
"positionTitle": "Managing Director"
}
}]
}]
},
{
"name": "Juicing",
"engagements": [{
"name": "347343",
"members": [{
"id": "4546", "account": {
"id": "001b000003WnPy1AAF", "fullName": "jeff bint"
},
"position": {
"id": "35006",
"positionTitle": "Senior Manager, Energy"
}
}]
}]
}]
}]
}
My current result:
{
"name": "Annual meetings",
"engagementAreas": [{
"id": "1",
"engagementTypes": [{
"name": "forestry",
"engagements": []
}, {
"name": "houses",
"engagements": [{
"name": "engagement1",
"members": [{
"id": "e334",
"account": {
"id": "eefe"
},
"position": {
"id": "3434",
"positionTitle": "Senior Manager, Energy"
}
}]
}]
}, {
"name": "landscaping",
"engagements": [{
"name": "engagement1343",
"members": [{
"position": {
"id": "4545",
"positionTitle": "Senior Manager, Energy"
}
}]
}]
}]
}, {
"name": "community days",
"engagementTypes": [{
"name": "skyscraping",
"engagements": []
}, {
"name": "tennis",
"engagements": [{
"name": "engagement346",
"members": [{
"id": "34",
"account": {
"id": "3546"
},
"position": {
"id": "3999434",
"positionTitle": "Senior Manager, Energy"
}
}]
}]
}, {
"name": "Juicing",
"engagements": [{
"name": "347343",
"members": [{
"id": "4546",
"account": {
"id": "3545"
},
"position": {
"id": "35006",
"positionTitle": "Senior Manager, Energy"
}
}]
}]
}]
}]
}
Sure, the trick would be to first map your data into an object (so you don't have to search over both arrays all the time), and then conditionally set the value (as I saw that your first manager, doesn't really have a matching position).
So to create the dictionary for usage in your later model, you can first do
// first map the accountId to positions
const accountIdToPositionDict = individualData.reduce( (current, item) => {
current[item.account.id] = (item.positions.filter( position => position.isPrimary )[0] || {} ).positionTitle;
return current;
}, {} );
This would then have an object where accountIdToPositionDict["123"] would be Managing Director, and then change the duplicating logic into:
const updatedGraphTable = { ...graphData,
engagementAreas: graphData.engagementAreas.map(area => ({ ...area,
engagementTypes: area.engagementTypes.map(type => ({ ...type,
engagements: type.engagements.map(engagement => ({ ...engagement,
members: engagement.members.map(member => ({ ...member,
position: { ...member.position,
// use the found positionTitle, or the original one that was given
positionTitle: member.account && accountIdToPositionDict[member.account.id] || member.position.positionTitle
}
}))
}))}))
}))
};
Where the position would then be set based on the found accountId in the dictionary, or the original title if no match was found
const individualData = [{
"account": {
"id": "001b000003WnPy1AAF",
"fullName": "jeff bint"
},
"positions": [{
"id": "a16b0000004AxeBAAS",
"organizationId": "001b0000005gxmlAAA",
"organizationName": "a",
"positionTitle": "Senior Manager, Energy",
"positionLevel": "5-Middle Management & Advisers",
"isPrimary": true,
"startDate": "2016-10-07",
"endDate": null
}]
}, {
"account": {
"id": "0010X000048DDMsQAO",
"fullName": "edy long"
},
"positions": [{
"id": "a160X000004nKfhQAE",
"organizationId": "001b0000005gxmlAAA",
"organizationName": "a",
"positionTitle": "Managing Director",
"positionLevel": "4-Head of Business Unit/Head of Region",
"isPrimary": true,
"startDate": "2018-03-05",
"endDate": null
}]
}, {
"account": {
"id": "123",
"fullName": "john boer"
},
"positions": [{
"id": "325345634634",
"organizationId": "001b0000005gxmlAAA",
"organizationName": "a",
"positionTitle": "Managing Director",
"positionLevel": "4-Head of Business Unit/Head of Region",
"isPrimary": true,
"startDate": "2018-03-05",
"endDate": null
}]
}
];
const graphData = {
"name": "Annual meetings",
"engagementAreas": [{
"id": "1",
"engagementTypes": [{
"name": "forestry",
"engagements": []
},
{
"name": "houses",
"engagements": [{
"name": "engagement1",
"members": [{
"id": "e334", "account": {
"id": "eefe", "fullName": "jim bean"
},
"position": {
"id": "3434",
"positionTitle": "Manager"
}
}]
}]
},
{
"name": "landscaping",
"engagements": [{
"name": "engagement1343",
"members": [{
"id": "e334", "account": {
"id": "123", "fullName": "john boer"
},
"position": {
"id": "4545",
"positionTitle": "Senior Manager"
}
}]
}]
}
]
},
{
"name": "community days",
"engagementTypes": [{
"name": "skyscraping",
"engagements": []
},
{
"name": "tennis",
"engagements": [{
"name": "engagement346",
"members": [{
"id": "34", "account": {
"id": "0010X000048DDMsQAO", "fullName": "edy long"
},
"position": {
"id": "3999434",
"positionTitle": "Ultime Manager"
}
}]
}]
},
{
"name": "Juicing",
"engagements": [{
"name": "347343",
"members": [{
"id": "4546", "account": {
"id": "001b000003WnPy1AAF", "fullName": "jeff bint"
},
"position": {
"id": "35006",
"positionTitle": "Senior Ultimate Manager"
}
}]
}]
}]
}]
};
// first map the accountId to positions
const accountIdToPositionDict = individualData.reduce( (current, item) => {
current[item.account.id] = (item.positions.filter( position => position.isPrimary )[0] || {} ).positionTitle;
return current;
}, {} );
// then use it in the mapping function
const updatedGraphTable = { ...graphData,
engagementAreas: graphData.engagementAreas.map(area => ({ ...area,
engagementTypes: area.engagementTypes.map(type => ({ ...type,
engagements: type.engagements.map(engagement => ({ ...engagement,
members: engagement.members.map(member => ({ ...member,
position: { ...member.position,
// use the found positionTitle, or the original one that was given
positionTitle: member.account && accountIdToPositionDict[member.account.id] || member.position.positionTitle
}
}))
}))}))
}))
};
console.log( updatedGraphTable );
Try the code below.
accountPositions = {};
IndividualData.forEach((data) => {
accountPositions[data.account.id] = data.positions.filter((pos) => {return pos.isPrimary})[0].positionTitle;
});
graphData.engagementAreas.forEach((area) => {
area.engagementTypes.forEach((type) => {
type.engagements.forEach((engagement) => {
engagement.members.forEach((member) => {
if (!accountPositions[member.account.id]) return;
console.log('position updated from ', member.position.positionTitle, 'to', accountPositions[member.account.id]);
member.position.positionTitle = accountPositions[member.account.id];
});
});
});
});

Normalising JSON data

{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
}
This is JSON for an article
{
result: "123",
entities: {
"articles": {
"123": {
id: "123",
author: "1",
title: "My awesome blog post",
comments: [ "324" ]
}
},
"users": {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" }
},
"comments": {
"324": { id: "324", "commenter": "2" }
}
}
}
Im currently looking through redux tutorials, they give a helper which normalise JSON data, does anyone know what type of normalisation this is?

How do I filter an array of data by id or name using another array of data to display in React Table?

I have a role-template array that gives each role a name, and a description. It also has a nested object with an array of permissions that are identified by id.
{
"data": [
{
"id": "1",
"type": "role-templates",
"attributes": {
"name": "Org Admin"
},
"relationships": {
"permissions": {
"data": [
{ "type": "permissions", "id": "1" },
{ "type": "permissions", "id": "2" },
{ "type": "permissions", "id": "3" },
{ "type": "permissions", "id": "4" },
{ "type": "permissions", "id": "5" },
{ "type": "permissions", "id": "6" },
{ "type": "permissions", "id": "7" },
{ "type": "permissions", "id": "8" },
{ "type": "permissions", "id": "9" },
{ "type": "permissions", "id": "10" },
{ "type": "permissions", "id": "11" },
{ "type": "permissions", "id": "12" },
{ "type": "permissions", "id": "13" },
{ "type": "permissions", "id": "14" },
{ "type": "permissions", "id": "15" },
{ "type": "permissions", "id": "17" },
{ "type": "permissions", "id": "18" },
{ "type": "permissions", "id": "19" },
{ "type": "permissions", "id": "20" },
{ "type": "permissions", "id": "21" },
{ "type": "permissions", "id": "23" },
{ "type": "permissions", "id": "24" }
]
}
}
},
{
"id": "2",
"type": "role-templates",
"attributes": { "name": "Data Admin" },
"relationships": {
"permissions": {
"data": [
{ "type": "permissions", "id": "1" },
{ "type": "permissions", "id": "2" },
{ "type": "permissions", "id": "3" },
{ "type": "permissions", "id": "4" },
{ "type": "permissions", "id": "5" },
{ "type": "permissions", "id": "6" }
]
}
}
},
{
"id": "3",
"type": "role-templates",
"attributes": {
"name": "Setup Admin"
},
"relationships": {
"permissions": {
"data": [{ "type": "permissions", "id": "8" }]
}
}
},
{
"id": "4",
"type": "role-templates",
"attributes": { "name": "Data Consumer"},
"relationships": {
"permissions": {
"data": [
{ "type": "permissions", "id": "11" },
{ "type": "permissions", "id": "13" }
]
}
}
},
{
"id": "5",
"type": "role-templates",
"attributes": { "name": "APT User" },
"relationships": {
"permissions": {
"data": [
{ "type": "permissions", "id": "17" },
{ "type": "permissions", "id": "18" },
{ "type": "permissions", "id": "19" }
]
}
}
},
{
"id": "6",
"type": "role-templates",
"attributes": {
"name": "User Admin"
},
"relationships": {
"permissions": {
"data": [
{ "type": "permissions", "id": "21" },
{ "type": "permissions", "id": "23" }
]
}
}
}
],
"meta": { "record-count": 6 }
}
Now I have a permissions array that gives each permission a name, and an id. That id can be matched to the nested array in the role-template array. I want to match these two arrays by the permission.id property that each of these arrays posses. Then for each role that has a permission. I want to display an asterisk * for this
How can I do that?
[
{
"id": "1",
"type": "permissions",
"attributes": {
"name": "Administer Source List",
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "2" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "8" }
]
}
}
},
{
"id": "2",
"type": "permissions",
"attributes": {
"name": "Administer Common Layers",
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "2" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "8" }
]
}
}
},
{
"id": "3",
"type": "permissions",
"attributes": {
"name": "Do benchmark tagging"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "2" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "8" }
]
}
}
},
{
"id": "4",
"type": "permissions",
"attributes": {
"name": "Do trend mapping"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "2" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "8" }
]
}
}
},
{
"id": "5",
"type": "permisns",
"attributes": {
"name": "Map custom values (for each data source)"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "2" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "8" }
]
}
}
},
{
"id": "6",
"type": "permissions",
"attributes": {
"name": "Administer Data Sets"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "2" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "8" }
]
}
}
},
{
"id": "7",
"type": "permisns"
"attributes": {
"name": "Create Campaigns"
},
"relationships": {
"roles": {
"data": [{ "type": "roles", "id": "1" }, { "type": "roles", "id": "7" }]
}
}
},
{
"id": "8",
"type": "permissions",
"attributes": {
"name": "Access/modify campaign setup"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "3" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "9" }
]
}
}
},
{
"id": "9",
"type": "permissions",
"attributes": {
"name": "Launch campaigns"
},
"relationships": {
"roles": {
"data": [{ "type": "roles", "id": "1" }, { "type": "roles", "id": "7" }]
}
}
},
{
"id": "10",
"type": "permissions",
"attributes": {
"name": "Create org-wide survey-related notifications"
},
"relationships": {
"roles": {
"data": [{ "type": "roles", "id": "1" }, { "type": "roles", "id": "7" }]
}
}
},
{
"id": "11",
"type": "permissions",
"attributes": {
"name": "View Reports"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "4" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "10" }
]
}
}
},
{
"id": "12",
"type": "permissions",
"attributes": {
"name": "Modify prebuilt reports"
},
"relationships": {
"roles": {
"data": [{ "type": "roles", "id": "1" }, { "type": "roles", "id": "7" }]
}
}
},
{
"id": "13",
"type": "permissions",
"attributes": {
"name": "Create new reports"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "4" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "10" }
]
}
}
},
{
"id": "14",
"type": "permissions",
"attributes": {
"name": "Share reports with rest of org"
},
"relationships": {
"roles": {
"data": [{ "type": "roles", "id": "1" }, { "type": "roles", "id": "7" }]
}
}
},
{
"id": "15",
"type": "permissions",
"attributes": {
"name": "Share filters with rest of org"
},
"relationships": {
"roles": {
"data": [{ "type": "roles", "id": "1" }, { "type": "roles", "id": "7" }]
}
}
},
{
"id": "16",
"type": "permissions",
"attributes": {
"name": "Create portfolio"
},
"relationships": {
"roles": {
"data": []
}
}
},
{
"id": "17",
"type": "permissions",
"attributes": {
"name": "Access all portfolios (at org)"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "5" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "11" }
]
}
}
},
{
"id": "18",
"type": "permissions",
"attributes": {
"name": "Assign action plans"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "5" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "11" }
]
}
}
},
{
"id": "19",
"type": "permissions",
"attributes": {
"name": "Work on action plans"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "5" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "11" }
]
}
}
},
{
"id": "20",
"type": "permissions",
"attributes": {
"name": "Administer role templates for org"
},
"relationships": {
"roles": {
"data": [{ "type": "roles", "id": "1" }, { "type": "roles", "id": "7" }]
}
}
},
{
"id": "21",
"type": "permissions",
"attributes": {
"name": "Add/edit/delete non org-admin users at org"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "6" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "12" }
]
}
}
},
{
"id": "22",
"type": "permissions",
"attributes": {
"name": "Add/edit/dete ORg Admin users at org"
},
"relationships": {
"roles": {
"data": []
}
}
},
{
"id": "23",
"type": "permissions",
"attributes": {
"name": "Administer access patterns at org"
},
"relationships": {
"roles": {
"data": [
{ "type": "roles", "id": "1" },
{ "type": "roles", "id": "6" },
{ "type": "roles", "id": "7" },
{ "type": "roles", "id": "12" }
]
}
}
},
{
"id": "24",
"type": "permissions",
"attributes": {
"name": "Switch user (\"Impersonate\" another user)"
},
"relationships": {
"roles": {
"data": [{ "type": "roles", "id": "1" }, { "type": "roles", "id": "7" }]
}
}
}
]
My react table looks like this right now:
What I want to do is to put an asterisk * in every cell for the permission that each role has.
My React component currently looks like this:
class SystemRoleTemplatesContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
permissionList: [],
roleTemplateList: [],
permissionsGroup: []
};
}
componentDidMount = () => {
this.getTableData();
}
getTableData = () => {
store.dispatch(api.getRoletemplates()).then((result) => {
const permissionHeader = [{
Header: "Permissions",
accessor: "permission"
}]
const roleTemplateItems = result.body.data.map((data) => {
return {
id: data.relationships.permissions.data.map((data)=>{
return {
id: data.id
}
}),
Header: data.attributes.name,
accessor: data.attributes.name.replace(/\s/g, '')
}
});
const roleTemplate = permissionHeader.concat(roleTemplateItems)
this.setState(() => ({
"roleTemplateList": roleTemplate
}));
});
store.dispatch(api.getPermissions()).then((result) => {
const permissionItems = result.body.data.map((data) => {
return {
id: data.id,
permission: data.attributes.name
}
});
this.setState(() => ({
"permissionList": permissionItems
}));
});
}
render() {
const {isLoading,roleTemplateList, permissionList} = this.state;
if (isLoading) {
return <LoadingAnimation />;
}
return (
<div className="role-management-form">
<div className="admin-user-container-title">
<Row>
<Col md={8}>
<h3>Manage Roles Template for System</h3>
</Col>
</Row>
</div>
<Table
columns={roleTemplateList}
className="organization-tbl"
data={permissionList}
defaultPageSize={50}
minRows={0}
/>
</div>
);
}
}
So I was able to use lodash to accomplish this.
class SystemRoleTemplatesContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false,
permissionList: [],
roleTemplateList: []
};
}
componentDidMount = () => {
this.getTableData();
}
getTableData = () => {
store.dispatch(api.getRoletemplates()).then((result) => {
const permissionHeader = [{
Header: "Permissions",
accessor: "permission"
}]
const roleTemplateItems = result.body.data.map((data) => {
return {
id: data.relationships.permissions.data.map((data)=>{
return {
id: data.id
}
}),
Header: data.attributes.name,
accessor: data.attributes.name.replace(/\s/g, '')
}
});
const roleTemplate = permissionHeader.concat(roleTemplateItems)
this.setState(() => ({
"roleTemplateList": roleTemplate
}));
});
store.dispatch(api.getPermissions()).then((result) => {
const permissionItems = result.body.data.map((data) => {
return {
id: data.id,
permission: data.attributes.name
}
});
this.setState(() => ({
"permissionList": permissionItems
}));
});
}
render() {
const {isLoading,roleTemplateList, permissionList} = this.state;
const updatedList = permissionList.map(permission => {
return roleTemplateList.reduce((permAcc, role) => {
const match = _.find(role.id, {'id': permAcc.id});
if(typeof match !== 'undefined' && role.accessor !== 'permission') {
permAcc[role.accessor] = '*';
} else if(role.accessor !== 'permission') {
permAcc[role.accessor] = '';
}
return permAcc;
}, permission);
});
if (isLoading) {
return <LoadingAnimation />;
}
return (
<div className="role-management-form">
<div className="admin-user-container-title">
<Row>
<Col md={8}>
<h3>Manage Roles Template for System</h3>
</Col>
</Row>
</div>
<Table
columns={roleTemplateList}
className="organization-tbl"
data={updatedList}
defaultPageSize={50}
minRows={0}
/>
</div>
);
}
}

JavaScript - Picking data with XMLHttpRequest

I'm having problems with my code, where I need to pick data with a JSON query from an API.
Here is the JSON body what I receive from the query:
{
"status": "success",
"reservations": [
{
"id": "38199",
"subject": "Koneiden vaihto",
"modifiedDate": "2017-05-16T12:46:17",
"startDate": "2017-06-21T08:00:00",
"endDate": "2017-06-21T22:00:00",
"resources": [
{
"id": "124",
"type": "room",
"code": "FRAMIF407",
"parent": {
"id": "4",
"type": "building",
"code": "FramiF",
"name": "Frami F"
},
"name": "Frami F407 (atk 34)"
}
],
"description": ""
},
{
"id": "30505",
"subject": "Alumnitapahtuman etukäteisjärjestelyt",
"modifiedDate": "2017-04-19T09:36:02",
"startDate": "2017-06-21T08:00:00",
"endDate": "2017-06-21T22:00:00",
"resources": [
{
"id": "104",
"type": "room",
"code": "FRAMIF144",
"parent": {
"id": "4",
"type": "building",
"code": "FramiF",
"name": "Frami F"
},
"name": "Frami F144 (lasipalatsi 120)"
}
],
"description": ""
},
{
"id": "38864",
"subject": "Koneiden vaihto/säilytystila",
"modifiedDate": "2017-06-21T06:03:07",
"startDate": "2017-06-21T08:00:00",
"endDate": "2017-06-21T22:00:00",
"resources": [
{
"id": "107",
"type": "room",
"code": "FRAMIF211",
"parent": {
"id": "4",
"type": "building",
"code": "FramiF",
"name": "Frami F"
},
"name": "Frami F211 (fysioterapia/teoria)"
}
],
"description": ""
},
{
"id": "38335",
"subject": "Koneiden vaihto",
"modifiedDate": "2017-05-16T12:48:32",
"startDate": "2017-06-21T08:00:00",
"endDate": "2017-06-21T22:00:00",
"resources": [
{
"id": "127",
"type": "room",
"code": "FRAMIF410",
"parent": {
"id": "4",
"type": "building",
"code": "FramiF",
"name": "Frami F"
},
"name": "Frami F410 (atk 34)"
}
],
"description": ""
},
{
"id": "38426",
"subject": "Koneiden vaihto",
"modifiedDate": "2017-05-16T12:49:25",
"startDate": "2017-06-21T08:00:00",
"endDate": "2017-06-21T22:00:00",
"resources": [
{
"id": "128",
"type": "room",
"code": "FRAMIF411",
"parent": {
"id": "4",
"type": "building",
"code": "FramiF",
"name": "Frami F"
},
"name": "Frami F411 (atk 34)"
}
],
"description": ""
},
{
"id": "43898",
"subject": "Varattu plinttien varastointiin",
"modifiedDate": "2017-06-12T08:54:31",
"startDate": "2017-06-21T08:00:00",
"endDate": "2017-06-21T22:00:00",
"resources": [
{
"id": "106",
"type": "room",
"code": "FRAMIF210",
"parent": {
"id": "4",
"type": "building",
"code": "FramiF",
"name": "Frami F"
},
"name": "Frami F210 (teoria 36)"
}
],
"description": ""
},
{
"id": "38267",
"subject": "Koneiden vaihto",
"modifiedDate": "2017-06-21T06:03:07",
"startDate": "2017-06-21T08:00:00",
"endDate": "2017-06-21T22:00:00",
"resources": [
{
"id": "126",
"type": "room",
"code": "FRAMIF409",
"parent": {
"id": "4",
"type": "building",
"code": "FramiF",
"name": "Frami F"
},
"name": "Frami F409 (atk 34)"
}
],
"description": ""
}
]
}
I need to pick up the all the names from the body, which are for example :
"Frami F407 (atk 34)", "Frami F144 (lasipalatsi 120)",
"Frami F211 (fysioterapia/teoria)", "Frami F410 (atk 34)
Here's how I process the data in order to get the names;
var jsonQuery = {
"startDate": startDate,
"endDate": endDate,
"building": [building]
};
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var json = JSON.parse(xhr.responseText);
console.log(xhr.responseText);
var rooms = [];
for (var i = 0; i < json.reservations.length; i++) {
if (json.reservations[i].resources != null) {
for (var j = 0; j < json.reservations[i].resources.length; j++) {
var reservation = json.reservations[i];
var resource = json.reservations[i].resources[j];
if (resource.type === "room") {
if (rooms.indexOf("code")) {
rooms.push(resource.name);
}
}
}
}
}
}
};
xhr.open("POST", "URL", true, "API-key", "");
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(jsonQuery));
This is how it should work : https://jsfiddle.net/p474djan/3/
But the problem is, when I run it through JSON.parse() and check in the console log, it keeps the first two names ("Frami F407 (atk 34)" and "Frami F144 (lasipalatsi 120)") but removes all the rest of the names. Any idea why this is happening?
I am not able to find any issue on your code but here it is my suggestion you can achieve the same via underscore.js without any looping and so on
https://jsfiddle.net/p474djan/5/
document.getElementById("pageOne").innerHTML = _.pluck(_.flatten(_.pluck(json["reservations"], 'resources')), 'name').join("<br/>")
Please have a look in to this

Categories