Populate grid with row/column coordinates in extjs - javascript

I'm trying to populate an extjs grid with data from json. The values I need to populate in the cells are in an object that gives the row and column number. I'm not sure how to get the values into the correct cells with this json structure.
Here is the json:
{
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/reports"
}
},
"columns" : [ {
"softwareBuild" : {
"buildId" : 10,
"generation" : "Alpha",
"build" : "1.0"
},
"eventTypeDisplay" : "Event Name 1"
}, {
"softwareBuild" : {
"buildId" : 10,
"generation" : "Beta",
"build" : "2.0"
},
"eventTypeDisplay" : "Event Name 1"
}],
"entries" : [ {
"row" : 0,
"column" : 0,
"value" : 10
}, {
"row" : 0,
"column" : 1,
"value" : 20
}, {
"row" : 1,
"column" : 0,
"value" : 30
}, {
"row" : 1,
"column" : 1,
"value" : 40
} ],
"rows" : [ {
"metricTypeId" : 1,
"metricName" : "Name 1",
"source" : "1",
}, {
"metricTypeId" : 2,
"metricName" : "Name 2",
"source" : "2",
}]
}
Here is the grid view:
Ext.create('Ext.grid.Panel', {
renderTo: document.body,
store: 'DataStore',
width: 400,
height: 200,
title: 'Software Metrics',
columns: [
{
text: 'Dynamic Column Name',
dataIndex: ''
}
]
});
Here is the model and store:
Ext.define('DataModel', {
extend: 'Ext.data.Model',
fields: [ 'value', 'generation', 'build', 'metricName', 'source' ]
});
Ext.define('DataStore', {
extend: 'Ext.data.Store'
model: 'DataModel',
proxy: {
type: 'rest',
url : 'api/reports'
}
});
Another question I have is how to populate the column headers with the "build" value from the columns array in the json object. And how to populate the cells in the first column with "metricName" from the rows array. But that could be for another question.

This is a process that will take time so I'll tell you what you need to do:
1 - Get your JSON structure and assign it to a variable, you should probably use Ext.Ajax.request for this.
2 - Loop through the columns object and create another object that is a valid column format for ExtJS something like:
var columns = [{
text : '1.0',
dataIndex: 'Alpha'
},{
text: '2.0',
dataIndex : 'Beta'
}];
3 - Apply the columns to your grid using grid.reconfigure(columns);
4 - Your model should have fields : ['Alpha', 'Beta']
5 - Your store should use a memory proxy now since your grabbed the data using Ext.Ajax.request.
6 - Loop through your entries object and get the total number of rows that should be added.
var entries = [{
"row" : 0,
"column" : 0,
"value" : 10
}, {
"row" : 0,
"column" : 1,
"value" : 20
}, {
"row" : 1,
"column" : 0,
"value" : 30
}, {
"row" : 1,
"column" : 1,
"value" : 40
}];
var rows = [];
for (var i=0;i<entries.length;i++) {
var currentRow = entries[i].row,
currentColumn = entries[i].column,
columnName = columns[currentColumn].dataIndex;
if(currentRow > rows.length - 1) {
rows.length = currentRow + 1;
}
if (!rows[currentRow]) rows[currentRow] = {};
rows[currentRow][columnName] = entries[i].value;
}
7 - Add assign the rows value to your store using store.loadRawData
Fiddle: https://fiddle.sencha.com/#fiddle/t2g

Related

Transform an explicit JSON payload into an array driven generic payload?

I am currently working in a project that has insisted in explicitly defining over 1,700 questions into a JSON data schema for an API and its getting out of control. I have been suggesting a more generic structure to the schema and let the data do the talking to tell you what the context is.
Whilst there are debates happening around which schema to use, we have decided on our internal systems, to go ahead and use a more generic model even if the externally facing model is the explicit one. This means we need an adapter to convert from one to the other, until such time as we can just use the one we wanted in the first place.
The business is a Java shop, I don't know whether to advise to build the adapter in Java or whether we can incorporate some lightweight JavaScript to do the work, maybe in the form of a configuration.
My question is: How would you approach converting the first JSON example into the second JSON example? It maps from explicitly defined objects to generic objects in arrays. Thanks for considering my question.
Example One
{
"nested_object" : {
"department_one" : {
"floor" : "4",
"product_one" : {
"quantity" : 10,
"size" : "L"
},
"product_two" : {
"quantity" : 5,
"size" : "S"
}
},
"department_two" : {
"floor" : "2",
"product_thirteen" : {
"quantity" : 1,
"size" : "M"
},
"product_eleven" : {
"quantity" : 8,
"size" : "L"
}
}
}
}
Example Two
{
"departments" : [
{
"department_name" : "department_one",
"floor" : "4",
"products" : [
{
"product_name" : "product_one",
"quantity" : 10,
"size" : "L"
},
{
"product_name" : "product_two",
"quantity" : 5,
"size" : "S"
}
]
},
{
"department_name" : "department_two",
"floor" : "2",
"products" : [
{
"product_name" : "product_thirteen",
"quantity" : 1,
"size" : "M"
},
{
"product_name" : "product_eleven",
"quantity" : 8,
"size" : "L"
}
]
}
]
}
You could use a combination of Object.keys (to grab product and department names). Below is a quick implementation.
const obj1 = {
"nested_object" : {
"department_one" : {
"floor" : "4",
"product_one" : {
"quantity" : 10,
"size" : "L"
},
"product_two" : {
"quantity" : 5,
"size" : "S"
}
},
"department_two" : {
"floor" : "2",
"product_thirteen" : {
"quantity" : 1,
"size" : "M"
},
"product_eleven" : {
"quantity" : 8,
"size" : "L"
}
}
}
}
const transformedObj = {
departments: [ ],
};
//holds all department names
const departmentKeys = Object.keys(obj1.nested_object)
const departmentsArr = departmentKeys.map((key) => {
const floor = obj1.nested_object[key].floor
//remove floor reference, since we already stored the value above
delete obj1.nested_object[key].floor
//holds all product names
const productsKeysArr = Object.keys(obj1.nested_object[key])
//holds all product objects for respective department
const productsArr = productsKeysArr.map((product) => {
const quantity = obj1.nested_object[key][product].quantity
const size = obj1.nested_object[key][product].size
return {
product_name: product,
quantity: quantity,
size: size
}
})
return {
department_name: key,
floor: floor,
products: productsArr
}
})
//assign departments array to transformed object
transformedObj.departments = departmentsArr
console.log(transformedObj)
This would be my take on this. I like conciseness and expressiveness in implementations:
const data = { "nested_object": { ... }}
Object.entries(data.nested_object).map(([department_name, {floor, ...ps}]) => ({
department_name,
floor,
products: Object.entries(ps).map(([product_name, p]) => ({product_name, ...p}))
}))

Javascript way of performing basic merge on two object [duplicate]

This question already has answers here:
Merge two javascript objects adding values of common properties
(4 answers)
How to merge objects and sum just some values of duplicate objects? [duplicate]
(1 answer)
Closed 2 years ago.
I have two objects that look like:
{
"data" : [
{
"name" : "toyota",
"type" : "cars",
"totals" : {
"invalid" : 4,
"valid" : 14,
"percentage" : 77.78,
"total" : 18
}
}
],
"report_id": "123wa31a22aba05"
}
I would like to merge those two objects into one object with the following set of rules:
Every two cars that have the same name and type in the data should be merged. This means that totals will be:
"totals": {
"invalid": "invalidA" + "invalidB"
"valid": "validA" + "validB"
"percentage" : calculatePercentage("invalid","valid")
"total": "invalid" + "valid"
}
If there is only sub-object with some name and type, it will just push it as it to the merged report.
What I thought: Copy object one to result object. Then iterate over the second object and insert the elements into the result object (merge if needed). I would use the for loop as I'm used from Java, but it doesn't feel a good js code. What is the proper way to merge those two object in JS?
Example to make it easier:
Object 1:
{
"data" : [
{
"name" : "toyota",
"type" : "cars",
"totals" : {
"invalid" : 4,
"valid" : 14,
"percentage" : 77.78,
"total" : 18
}
}
],
"report_id": "123wa31a22aba05"
}
Object 2:
{
"data" : [
{
"name" : "toyota",
"type" : "cars",
"totals" : {
"invalid" : 2,
"valid" : 5,
"percentage" : 71.42,
"total" : 7
}
}
],
"report_id": "123wa31a22aba06"
}
Result:
{
"data" : [
{
"name" : "toyota",
"type" : "cars",
"totals" : {
"invalid" : 6,
"valid" : 19,
"percentage" : 76.0,
"total" : 25
}
}
]
}
This solution might help you.
var a = {
"data": [
{
"name": "toyota",
"type": "cars",
"totals": {
"invalid": 4,
"valid": 14,
"percentage": 77.78,
"total": 18
}
}
],
"report_id": "123wa31a22aba05"
},
b = {
"data": [
{
"name": "toyota",
"type": "cars",
"totals": {
"invalid": 2,
"valid": 5,
"percentage": 71.42,
"total": 7
}
}
],
"report_id": "123wa31a22aba06"
},
c = [...a.data, ...b.data];
var tmp = [];
for (let i = 0; i < c.length; i++) {
for (let j = i + 1; j < c.length; j++) {
if(c[i].name == c[j].name) {
c[i].totals.invalid += c[j].totals.invalid;
c[i].totals.valid += c[j].totals.valid;
c[i].totals.total += c[j].totals.total;
c[i].totals.percentage = (c[i].totals.valid / c[i].totals.total) * 100;
c.splice(j, 1)
}
}
}
console.log(c);

Read data from arrays in javascript

I'm trying to read data from an array in JSON with javascript but I can't get it working. This is the segment of the JSON file from wich I want to read the data, I want to read the age variable from different arrays:
{
"failCount" : 1,
"skipCount" : 15,
"totalCount" : 156,
"childReports" :
[
{
"result" :
{
duration : 0.97834,
empty : false,
suites :
[
cases :
[
{
"age" : 0,
"status" : Passed
}
{
"age" : 15,
"status" : Passed
}
{
"age" : 3,
"status" : failed
}
]
]
}
}
]
}
I've tried this:
for (var i = 0; i < jsonData.childReports.suites.cases.length; i++)
{
var age = jsonData.childReports.suites.cases[i];
}
But it doesn't work. What would be the best way to do this?
Thanks in advance,
Matthijs.
Try the following code:
for (var i = 0; i < jsonData.childReports[0].result.suites[0].cases.length; i++) {
var age = jsonData.childReports[0].result.suites[0].cases[i].age;
}
Correct Json:
{
"failCount" : 1,
"skipCount" : 15,
"totalCount" : 156,
"childReports" : [
{
"result" : {
duration : 0.97834,
empty : false,
suites : [{
cases : [
{
"age" : 0,
"status" : "Passed"
},
{
"age" : 15,
"status" : "Passed"
},
{
"age" : 3,
"status" : "failed"
}
]}
]
}
}]
}
This way you can achieve that :
var data = {
"failCount" : 1,
"skipCount" : 15,
"totalCount" : 156,
"childReports" : [
{
"result" : {
duration : 0.97834,
empty : false,
suites : [{
cases : [
{
"age" : 0,
"status" : "Passed"
},
{
"age" : 15,
"status" : "Passed"
},
{
"age" : 3,
"status" : "failed"
}
]}
]
}
}]
};
for (var i = 0; i < data.childReports[0].result.suites[0].cases.length; i++) {
console.log(data.childReports[0].result.suites[0].cases[i].age);
}
DEMO

Trying to get the sum for each Object

I have been trying to figure this out, but I seem to be going nowhere. Basically I have a JSON that outputs.
[
{
"gosuResponse" : {
"tokenId" : "60e2d532-3d1c-4a95-adbd-aa352984c125",
"page" : 1,
"pageSize" : 1000,
"nbLinesTotal" : 15,
"serials" : {
"serial" : [ "272072207980" ]
},
"data" : {
"row" : [ {
"col" : [ "2015-02-10", "", "1"]
}, {
"col" : [ "2015-02-10", "BNP-Blogs", "1504"]
}, {
"col" : [ "2015-02-10", "BNP", "66"]
}, {
"col" : [ "2015-02-10", "GOOMPlayer-Site", "6"]
}, {
"col" : [ "2015-02-10", "podcast", "19"]
}, {
"col" : [ "2015-02-10", "stream", "10"]
}, {
"col" : [ "2015-02-09", "", "6"]
}, {
"col" : [ "2015-02-09", "BNP-Blogs", "1742"]
}, {
"col" : [ "2015-02-09", "BNP", "61"]
}, {
"col" : [ "2015-02-09", "GOOMPlayer-Site", "2"]
}, {
"col" : [ "2015-02-09", "podcast", "18"]
}, {
"col" : [ "2015-02-09", "stream", "8"]
}, {
"col" : [ "2015-02-08", "", "7"]
}, {
"col" : [ "2015-02-01", "stream", "8"]
} ]
}
}
}
]
Since there are similar names, I grouped them together using underscore.js
var items = result[0].gosuResponse.data.row;
var groups = _(items).groupBy(function(o) {
return o.col[1];
});
console.log(groups);
This outputs,
Object
- BNP : Array[4]
- 0 : Object
- col : Array[3]
0 : '2015-02-10"
1 : 'BNP'
2: '66'
- 1 : Object
- col : Array[3]
0 : '2015-02-10"
1 : 'BNP'
2: '66'
I am trying to add up the number value in position 2 for each Object.
I tested with one key in my Plunkr, but I was wondering if there is a way to do it for all objects?
My Plunkr http://plnkr.co/edit/nNwNoAiUz4PKV8ucaPc1?p=preview
I think there is no reasons to group items:
var sum = {};
_.each(items, function(row) {
var col = row.col;
if (sum.hasOwnProperty(col[1])) {
sum[col[1]] += parseInt(col[2]) || 0;
} else {
sum[col[1]] = parseInt(col[2]) || 0;
}
});
But note I'm relatively new to underscore.js and did not know much about its specific tricks.
Update:
I've found a native underscore.js solution with using groups also:
var groups = _(items).groupBy(function(o) {
return o.col[1];
});
var sum2 = {};
_.each(groups, function(group, key) {
sum2[key] = _.reduce(group, function(memo, item) {
return memo + (parseInt(item.col[2]) || 0);
}, 0);
});

mongodb update on JSON array

I have this data in Mongo:
{'_id':1,
'name':'Root',
'taskId':1,
'parentId':"",
'path':[1],
'tasks':[ {"taskId":3,parentId:1,name:'A',type:'task'},
{"taskId":4,parentId:1,name:'D',type:'task'},
{"taskId":5,parentId:4,name:'B',type:'task'},
{'type':'project' , 'proRef':2},
{"taskId":6,parentId:3,name:'E',type:'task'},
{"taskId":7,parentId:6,name:'C',type:'task'}]
}
Now I want to update taskId 6 with new Json data .
var jsonData = {"taskId":6,"name":'Sumeet','newField1':'Val1','newField2':'Val2'}
query should update if field is available else add new key to existing .Output Like
{"taskId":6,parentId:3,name:'Sumeet',type:'task','newField1':'Val1','newField2':'Val2'}]
I have tried few query but it is completely replacing json .
db.projectPlan.update({_id:1,'tasks.taskId':6},{$set :{'tasks.$':jsonData }});
Thanks in advance for your helps!
Sumeet
You need to transform the jsonData variable into something that can be passed to update. Here's an example that does exactly what you want with your sample document:
var updateData = {};
for (f in jsonData) {
if (f != "taskId") updateData["tasks.$."+f]=jsonData[f];
};
db.projectPlan.update({_id:1, 'tasks.taskId':6}, {$set:updateData})
Result:
{ "_id" : 1,
"name" : "Root",
"taskId" : 1,
"parentId" : "",
"path" : [ 1 ],
"tasks" : [
{ "taskId" : 3, "parentId" : 1, "name" : "A", "type" : "task" },
{ "taskId" : 4, "parentId" : 1, "name" : "D", "type" : "task" },
{ "taskId" : 5, "parentId" : 4, "name" : "B", "type" : "task" },
{ "type" : "project", "proRef" : 2 },
{ "taskId" : 6, "parentId" : 3, "name" : "Sumeet", "type" : "task", "newField1" : "Val1", "newField2" : "Val2" },
{ "taskId" : 7, "parentId" : 6, "name" : "C", "type" : "task" }
] }
You will need to merge the document manually:
var jsonData = {"taskId":5,"name":'Sumeet','newField1':'Val1','newField2':'Val2'};
db.projectPlan.find({ _id: 1 }).forEach(
function(entry) {
for (var taskKey in entry.tasks) {
if (entry.tasks[taskKey].taskId === jsonData.taskId) {
printjson(entry.tasks[taskKey]);
for (var taskSubKey in jsonData) {
entry.tasks[taskKey][taskSubKey] = jsonData[taskSubKey];
}
printjson(entry.tasks[taskKey]);
}
}
db.projectPlan.save(entry);
}
);
Obviously you can leave away the printjson statements. This is simply to see that the merging of the original tasks with the new tasks works. Note that this query will only update a single document as long as the _id field is unique.

Categories

Resources