Ag-grid tree data feature is not showing data - javascript

I am trying to make this work for two days now. I am trying to show Tree data in Ag-grid in ReactJS using this article : https://www.ag-grid.com/javascript-grid-server-side-model-tree-data/
Maybe I missed something from their documentation. Please someone help.
Obviously their Tree data is an enterprise feature and I referred to their server side model.
Expected functionality :
Tree data feature with data from server.
Two modes : one time fetching all data
Or lazy loading for batch wise data
My JSON is as follows:
[{
"employeeId": 101,
"employeeName": "Erica Rogers",
"jobTitle": "CEO",
"employmentType": "Permanent",
"children": [{
"employeeId": 102,
"employeeName": "Malcolm Barrett",
"jobTitle": "Exec. Vice President",
"employmentType": "Permanent",
"children": [
{
"employeeId": 103,
"employeeName": "Leah Flowers",
"jobTitle": "Parts Technician",
"employmentType": "Contract"
},
{
"employeeId": 104,
"employeeName": "Tammy Sutton",
"jobTitle": "Service Technician",
"employmentType": "Contract"
}
]
}]
}]
And
Code:
import React, { Component } from 'react';
import { AgGridReact } from 'ag-grid-react';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-balham.css';
import 'ag-grid-enterprise';
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
columnDefs: [
{ field: "jobTitle" },
{ field: "employmentType" }
],
matchGridData: [],
autoGroupColumnDef: {
headerName: "Model",
field: "model",
cellRenderer: 'agGroupCellRenderer',
cellRendererParams: {
checkbox: true
}
},
// indicate if row is a group node
isServerSideGroup: function (dataItem) {
return dataItem.group;
},
// specify which group key to use
getServerSideGroupKey: function (dataItem) {
return dataItem.MatchGroup;
}
}
}
render() {
return (
<div
className="ag-theme-balham"
style={{
height: '500px',
width: '600px'
}}
>
<AgGridReact columnDefs={this.state.columnDefs} rowData={this.state.matchGridData} rowSelection="multiple"
onGridReady={params => this.gridApi = params.api} treeData={true} isServerSideGroup={this.state.isServerSideGroup}
getServerSideGroupKey={this.state.getServerSideGroupKey}
rowModelType='serverSide'
>
</AgGridReact>
</div>
);
}
EDIT:
I have prepared a small test repository on Github dedicated to this issue and in this GridExampleGrouping.js is being rendered but not GridExampleTreeServer.js
: https://github.com/HarvestAdmin/test-grid
getMatchingData = e => {
fetch('/Matching/ResultGrid.aspx/GetMatchingData', {
method: 'POST',
body: JSON.stringify({ userId: this.state.userId, executionId: this.state.matchOrExecutionId, outputType: this.state.outputType, action: this.state.action }),
headers: {
"Content-Type": "application/json; charset=UTF-8",
"Accept": "application/json, text/javascript, */*; q=0.01",
"X-Requested-With": "XMLHttpRequest"
}
})
.then(response => {
return response.json();
}, error => {
return error.json();
})
.then(jsonResponse => {
var result = JSON.parse(jsonResponse.d);
console.log(result);
this.setState({ matchGridData: result.SearchResults.Table });
});
}
}
Pic 1 : The output in browser :
Pic 2 : The console for above output:
Pic 3 : Even after applying a Trial license given by Ag-grid :

Upon contacting Ag-grid support team on Trial license, they recommended that I should use px instead of % to set height and width of the DIV element that contains Ag-grid element.
For some reason, giving discreet values rather than a percentage works.

Related

Clear database to update content with Notion API

I have a workspace in Notion, which I use to take notes for an app I have on Github.
I want to add a database which will show some download stats from different sources (incuding Github) using the beta Notion API.
Right now I can add information at the end of a database just fine, but I don't understand how to remove the content which was posted before. Or even update it if I can.
This is what I have so far:
import { Client } from "#notionhq/client";
import dotenv from "dotenv";
import { Octokit } from "#octokit/rest";
dotenv.config();
const octokit = new Octokit();
const notion = new Client({ auth: process.env.NOTION_TOKEN });
const databaseId = process.env.NOTION_DATABASE_ID;
async function addEntry(release, name, download_count, tag) {
try {
await notion.request({
path: "pages",
method: "POST",
body: {
parent: { database_id: databaseId },
properties: {
Version: {
title: [
{
text: {
content: release,
},
},
],
},
Name: {
rich_text: [
{
text: {
content: name,
},
},
],
},
"Download Count": {
type: "number",
number: download_count,
},
Tags: {
multi_select: [{ name: "Github" }, { name: tag }],
},
},
},
});
console.log("Success! Entry added.");
} catch (error) {
console.error(error.body);
}
}
(async () => {
const latest_release = await octokit.repos.listReleases({
owner: "ShadowMitia",
repo: "steam_randomiser",
});
const releases = latest_release.data;
let github_downloads = {};
for (let release of releases) {
for (let asset of release.assets) {
console.log(release["tag_name"], asset["name"], asset["download_count"]);
// github_downloads[asset["label"]];
addEntry(
`${release["tag_name"]}`,
`${asset["name"]}`,
asset["download_count"],
asset["name"].includes("linux") ? "Linux" : "Windows"
);
}
}
})();
To delete (archive) a page in a database. Set the archive parameter to true.
curl --location --request PATCH 'https://api.notion.com/v1/pages/YOUR_PAGE_ID' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_BOT_TOKEN' \
--data'{
"parent":{
"database_id":"YOUR_DATABASE_ID"
},
"archived": true,
"properties":{
"Name":{
"title":[
{
"text":{
"content":"A Test Page"
}
}
]
},
"Email": {
"email": "hello#test.com"
},
"multiselect_tags": {
"type": "multi_select",
"multi_select":[{
"name": "Duc Loi Market"
},
{
"name": "Rainbow Grocery"
}]
}
}
}'
To clear data in a page you would set the data to empty or null depending on the property being updated. For example, if you have an array, you would set the property to an empty array.
"multiselect_tags": {
"type": "multi_select",
"multi_select":[ {
"name": "Duc Loi Market"
},
{
"name": "Rainbow Grocery"
}
]
}
}
//Empty a multi_select property
"multiselect_tags": {
"type": "multi_select",
"multi_select":[]
}
If the property is a string, like the email property, set it to null
"Email": {
"email": "hello#test.com"
}
//Empty the value of the email property on a page
"Email": {
"email": null
}

How to map an array from json that contains two arrays?

I fetch data from json and try to display one of the arrays in my componenet but I get an error that map is not a function, what do I do wrong? How to get only one array of two? Is it array I have in json or an object?
import React, { Component } from 'react';
class Customer extends Component {
constructor() {
super();
this.state = {
customers : []
};
}
componentDidMount() {
fetch('myURL')
.then(response => response.json())
.then(json => this.setState({ customers: json}))
}
render () {
return (
<div>
{this.state.customers && this.state.customers.map(cust => (
<div>
<h1>{cust.CustomerName}</h1>
</div>
)
})}
</div>
)
}
}
export default Customer;
And my JSON file has two arrays that looks like this:
{
"fields": [
{
"id": "Customer_ID",
"description": "Customer ID",
"type": "Key",
},
{
"id": "Customer_ID",
"description": "Customer ID",
"type": "Key",
},
],
"list_items": [{"Customer_ID":1,"CustomerName":"ABS","CustomerType":"DTS"},
{"Customer_ID":2,"CustomerName":"Giu Sto","CustomerType":"STD"}]
}
You did not asign the items to customers in state. You should do it like this
componentDidMount() {
fetch('myURL')
.then(response => response.json())
.then(json => this.setState({ customers: json.list_items}))
}
I hope this solves your problem
Edit:
this.setState({customers:json}) will change customers state to an object which is not itterable and have the value of your json file customers:{fields: [...],list_items: [...]} but you only want list_items to be assigned to customers that's why you should access list_items from json and assign it directly to customers this.setState({customers:json.list_items_}
try logging whether the array is present or not.
const my_json = {
fields: [
{
id: "Customer_ID",
description: "Customer ID",
type: "Key",
},
{
id: "Customer_ID",
description: "Customer ID",
type: "Key",
},
],
list_items: [
{ Customer_ID: 1, CustomerName: "ABS", CustomerType: "DTS" },
{ Customer_ID: 2, CustomerName: "Giu Sto", CustomerType: "STD" },
],
};
my_json.list_items.map(customer => console.log(customer.CustomerName))

Material Table Get and Set Filter Values

How can I get and set the filter values programmatically using material-table?
I want users to be able to save filter configurations as reports and recall them as needed.
Get works with a hook on change:
onFilterChange={(filters) => {
console.log('onFilterChange', filters);
}}
result is an array of filter definitions per column, looks like:
[
// [...]
{
"column": {
"title": "Date",
"field": "file_date",
"type": "date",
"tableData": {
"columnOrder": 3,
"filterValue": "2020-11-10T15:20:00.000Z",
"groupSort": "asc",
"width": "...", // lots of css calc stuff... :(
"additionalWidth": 0,
"id": 4
}
},
"operator": "=",
"value": "checked"
}
]
setting the filter on mount could/should work with defaultFilter at each column definition.
There are two parts to this, the get and the set.
Get - handled through the use of the tableRef prop on the MaterialTable component
Set - handled through the defaultFilter value on a column object.
import MaterialTable from "material-table";
import React, { useRef } from "react";
import { tableIcons } from "./tableIcons";
const firstNameFilter = 'Neil'
function App() {
const tableRef = useRef<any>();
return (
<div>
<button onClick={saveFilters(tableRef)}>Filters</button> // GET OCCURS HERE
<MaterialTable
tableRef={tableRef}
icons={tableIcons}
columns={[
{ title: "First", field: "name", defaultFilter: firstNameFilter }, // SET OCCURS HERE
{ title: "Last", field: "surname" }
]}
data={[
{ name: "Neil", surname: "Armstrong" },
{ name: "Lance", surname: "Armstrong" },
{ name: "Bob", surname: "Hope" }
]}
options={{ filtering: true }}
title="Reports"
/>
</div>
);
}
function saveFilters(tableRef: React.MutableRefObject<any>) {
return function handler() {
const columns = tableRef?.current?.state.columns.map((column: any) => ({
field: column.field,
filterValue: column.tableData.filterValue
}));
console.log(JSON.stringify(columns, null, 2));
};
}
export { App };

Material UI - TreeView datastructure

I want to structure the data that I get from a server, so I can use the TreeView component from Material UI: https://material-ui.com/api/tree-view/
I'm fetching large amounts of data so I want to fetch child nodes from the server when the user clicks on the expand button. So
when the first node is expanded a HTTP request is sent to a server which returns all of the children of that node. When another node is expanded the children of that node is fetched etc.
On startup of the page I want to fetch the root node and its children. The JSON returned will look something like this:
{
"division": {
"id": "1234",
"name": "Teest",
"address": "Oslo"
},
"children": [
{
"id": "3321",
"parentId": "1234",
"name": "Marketing",
"address": "homestreet"
},
{
"id": "3323",
"parentId": "1234",
"name": "Development",
"address": "homestreet"
}
]
}
When expanding the Marketing node I want to make a HTTP call to fetch the children of this node. So I would get JSON like this:
{
"children": [
{
"id": "2212",
"parentId": "3321",
"name": "R&D",
"address": "homestreet"
},
{
"id": "4212",
"parentId": "3321",
"name": "Testing",
"address": "homestreet"
}
]
}
But I am confused on how to create such a data structure which can later be used my the TreeView component. How can I create such a structure?
For anyone still looking for a solution to this problem I've recently tackled it using a combination of the selected and expanded props in the TreeView API. See this Code Sandbox demo for an example of how to asynchronously load new children and expand their parent once they are loaded.
import React from "react";
import TreeView from "#material-ui/lab/TreeView";
import ExpandMoreIcon from "#material-ui/icons/ExpandMore";
import ChevronRightIcon from "#material-ui/icons/ChevronRight";
import TreeItem from "#material-ui/lab/TreeItem";
import TreeNode from "./TreeNode";
const mockApiCall = async () => {
return new Promise((resolve) => {
setTimeout(() => {
const nextId = Math.ceil(Math.random() * 100);
resolve([
{
id: `${nextId}`,
name: `child-${nextId}`,
children: []
},
{
id: `${nextId + 1}`,
name: `child-${nextId + 1}`,
children: []
}
]);
}, Math.ceil(Math.random() * 1000));
});
};
export default class Demo extends React.Component {
constructor(props) {
super(props);
this.state = {
expanded: [],
selected: "1",
tree: new TreeNode({
id: "1",
name: "src",
children: []
})
};
}
handleChange = async (event, nodeId) => {
const node = this.state.tree.search(nodeId);
if (node && !node.children.length) {
mockApiCall()
.then((result) => {
this.setState({ tree: this.state.tree.addChildren(result, nodeId) });
})
.catch((err) => console.error(err))
.finally(() => {
this.setState({
selected: nodeId,
expanded: [...this.state.expanded, nodeId]
});
});
}
};
createItemsFromTree = (tree) => {
if (tree.children.length) {
return (
<TreeItem key={tree.id} nodeId={tree.id} label={tree.name}>
{tree.children.length > 0 &&
tree.children.map((child) => this.createItemsFromTree(child))}
</TreeItem>
);
}
return <TreeItem key={tree.id} nodeId={tree.id} label={tree.name} />;
};
render() {
return (
<TreeView
defaultCollapseIcon={<ExpandMoreIcon />}
defaultExpandIcon={<ChevronRightIcon />}
selected={this.state.selected}
onNodeSelect={this.handleChange}
expanded={this.state.expanded}
>
{this.createItemsFromTree(this.state.tree)}
</TreeView>
);
}
}

React JS tree view to display api response

In my react application, I am implementing a tree view structure to display the api response in more readable format. I am using tree view-react-bootstrap for that.
import React from 'react';
import ReactDOM from 'react-dom';
import TreeView from 'treeview-react-bootstrap'
class Example extends React.Component {
constructor(){
super();
// SET YOUR DATA
this.state = {
data: [
{
text: "John Peter",
nodes: [
{
text: "ID: 11111",
nodes: [
{
text: "VIN"
},
{
text: "Policy Effective Date"
},
{
text: "Policy Expiration Date"
},
{
text: "Vehicle Make"
},
{
text: "Vehicle Model"
}
]
},
{
text: "ID: 123456",
nodes: [
{
text: "VIN"
},
{
text: "Policy Effective Date"
},
{
text: "Policy Expiration Date"
},
{
text: "Vehicle Make"
},
{
text: "Vehicle Model"
}
]
}
]
},
{
text: "Scott Brown"
}
]
}
}
render(){
return (
// RENDER THE COMPONENT
<TreeView data={this.state.data} />
);
}
}
export default Example
I am using dummy data for now but this is the format that I want my data to be displayed. The api response I have is "array of objects" and it is only in one level JSON format.
Sample response -
[
{
"id": "1234",
"name": "John Scott",
"vin": "45",
"make": "Toyota",
"model": "Etios"
},
{
"id": "4567",
"name": "James Scott",
"vin": "67",
"make": "Hyundai",
"model": "Etios"
}
]
If you see the response, I would like my key value to be printed in a tree structure.
Is there a way I can render this response to accommodate with treeview-react-bootstrap?
I am not sure if I need to use map function inside my render method to iterate and display the data and how will it work along.Can someone let me know if I am doing it right or is there any better way of doing it. thanks in advance.
You can transform the response something like this. Have just added a dummy response. Please check the following code and let me know if this helps:
import React from "react";
import ReactDOM from "react-dom";
import TreeView from "treeview-react-bootstrap";
import axios from "axios";
class Example extends React.Component {
constructor() {
super();
// SET YOUR DATA
this.state = {
data: []
};
}
componentDidMount() {
axios
.get("https://www.mocky.io/v2/5bb85d723000005f00f93bb6")
.then(data => {
let transformedData = data.data.map(d => {
return {
text: d.text,
nodes: [
{
text: "dummy 1",
nodes: []
}
]
};
});
this.setState({ data: transformedData });
});
}
render() {
return (
// RENDER THE COMPONENT
<TreeView data={this.state.data} />
);
}
}
ReactDOM.render(<Example />, document.getElementById("app"));
You can also see it in action here: https://codesandbox.io/s/73ryny9ywq?autoresize=1&hidenavigation=1

Categories

Resources