SOLVED: turns out I was importing the incorrect CSS which causes some pretty severe issues, read answer for more details
After implementing ag-grid, data is showing but I am unable to scroll at all.
I made a stackblitz here: https://stackblitz.com/edit/angular-ytr1jj.
The stackblitz works as expected but, for some reason, the exact same code fails to scroll in my app.
I have tried multiple ways of rendering the rows.
I have tried messing with the CSS to see if there is anything causing an overlap in the scrollbar.
so far no luck. I think it might have something to do with "pointer events"...
Update: I think that the virtual scroll requires the mouse event to be captured on the row, and for some reason the mouse event is not being captured and therefore can't scroll
<ag-grid-angular
#agGrid
style="width: 100%; height: 600px;"
class="ag-theme-balham"
[rowData]="rowData"
[columnDefs]="columnDefs"
>
</ag-grid-angular>
columnDefs = [
{ headerName: 'Make', field: 'make' },
{ headerName: 'Model', field: 'model' },
{ headerName: 'Price', field: 'price' }
];
rowData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 }
];
UPDATE 2: I am able to get the scrollbar to scroll if i set pointer-events: none to .ag-center-cols-viewport. the html seems to be updating on scroll and the row-index row-id etc is updating as it scrolls, however the table view seems to not to not show the current rows being inserted into the ref="ag-center-cols-viewport" (they are appearing in the html but they are not visible)
ANSWER
okay so, this is a bit ridiculous but here it goes
BAD
#import "~ag-grid/dist/styles/ag-grid.css";
#import "~ag-grid/dist/styles/ag-theme-material.css";
GOOD
#import 'ag-grid-community/dist/styles/ag-grid.css';
#import 'ag-grid-community/dist/styles/ag-theme-material.css';
After checking my package.json again I noticed I had 3 things of ag-grid under dependencies
"ag-grid",
"ag-grid-angular",
"ag-grid-community"
The CSS I was importing was from the old version of "ag-grid".
After removing "ag-grid" from package.json I imported the proper CSS and everything worked immediately...
Final Good Code
// package.json
"ag-grid-angular": "^20.0.0",
"ag-grid-community": "^20.0.0",
// _vendor.scss where I import most my node_modules css
// #import "~ag-grid/dist/styles/ag-grid.css";
// #import "~ag-grid/dist/styles/ag-theme-material.css";
#import 'ag-grid-community/dist/styles/ag-grid.css';
#import 'ag-grid-community/dist/styles/ag-theme-material.css';
Related
{ _id: ObjectId("62d3af6d0df67535575ee87e"),
time: '2022-07-17T09_39_19',
data:
[ { Manufacturer: 'iPollo',
Model: 'V1',
Release: 'June 2022',
'Size(mm)': { x: 314, y: 194, z: 290 },
'Weight(g)': 13000,
'Noise level': '70db',
'Fan(s)': '4',
'Power(w)': 3100,
Interface: 'Ethernet',
Memory: '6G',
Temperature: '5 - 25 °C',
Humidity: '10 - 90 %',
coins:
[ 'Ubiq',
'Ethereum',
'Ethereum Classic',
'Musicoin',
'Pirl',
'EtherGem',
'Callisto',
'QuarkChain' ],
available_stores:
[ { store_name: 'CoinMining Central',
url: 'https://coinminingcentral.com/collections/ipollo-miners/products/ipollo-v1-mini-ethereum-miner-3-6-gh-s?ref=uybdgyQD&ref=uybdgyQD',
price: '$21,959.49',
country: 'United Kingdom',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'AKMiner',
url: 'https://www.akminer.com/all-products/ipollo-v1-3600mh-eth-miner-most-powerful-eth-miner-for-2022?wpam_id=1',
price: '$20,399.00',
country: 'China',
stock: 'In stock(3 \ndays\n)',
isFreeShipping: false },
{ store_name: 'NHASH',
url: 'https://www.nhash.net/miners/94129954756763648?ref=3yrntphlqn',
price: '$20,999.00',
country: 'Hong Kong',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'BT-Miners',
url: 'https://bt-miners.com/products/2022-new-ipollo-v1-eth-etc-miner-3600mh-s-with-psu-and-cord-most-powerful-eth-miner-for-2022?ref=3yrntphlqn&ref=3yrntphlqn&variant=43048045183163',
price: '$21,000.00',
country: 'United States',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'ViperaTech',
url: 'https://www.viperatech.com/product/ipollo-v1-eth-etc-miner-3600mh-s/?ref=585',
price: '$21,900.00',
country: 'Canada',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'Safety Miner',
url: 'https://www.safetyminer.net/product-page/ipollo-v1-3-6gh-s?ref=3yrntphlqn',
price: '$25,103.16',
country: 'United Kingdom',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'Miner Bros',
url: 'https://www.cryptominerbros.com/product/ipollo-v1-3600mh-s-eth-etc-miner/?wpam_id=1',
price: '$27,499.00',
country: 'Honk Kong',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'AsicMarketPlace',
url: 'https://asicmarketplace.com/product/ipollo-v1-eth-miner-3600mh/?wpam_id=4',
price: '$27,550.00',
country: 'Honk Kong',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'MillionMiner',
url: 'https://www.millionminer.com/ipollo-v1-3600mhs--ethereum-miner-new-millionminercom.html?1000',
price: '$30,143.96',
country: 'Germany',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'Crypto Supply',
url: 'https://cryptosupply.de/product/ipollo-v1/?wpam_id=1',
price: '$30,900.08',
country: 'Germany',
stock: 'In stock(14 \ndays\n)',
isFreeShipping: false },
{ store_name: 'Casa Miners',
url: 'https://casaminers.com/collections/new-asic-1/products/ipollo-v1-3-6gh-s?ref=TTdMmJZNqvqtBI',
price: '$31,242.85',
country: 'Italia',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'iPollo',
url: 'https://ipollo.com/products/ipollo-v?ref=3yrntphlqn',
price: '$35,460.00',
country: 'China',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'Bitcoin Merch',
url: 'https://bitcoinmerch.com/products/ipollo-v1-3-6gh-s-eth-asic-miner?aff=2',
price: '$39,999.99',
country: 'United States',
stock: 'Out of stock',
isFreeShipping: false } ],
Algorithm_and_power:
[ { Algorithm_name: 'EtHash',
'hashrate(H/hour) ': 3600000000,
'power_consumption(W)': 3100 } ],
available_mining_pools:
[ { pool_name: 'Poolin',
url_link: 'https://www.poolin.com',
profit_type: 'FPPS',
profit_perc: 'FPPS' },
{ pool_name: 'SparkPool',
url_link: 'https://www.sparkpool.com/',
profit_type: 'PPS',
profit_perc: 0.01 },
{ pool_name: 'Ethermine',
url_link: 'https://ethermine.org',
profit_type: 'PPLNS',
profit_perc: 0.01 },
{ pool_name: 'ViaBTC',
url_link: 'https://pool.viabtc.com?refer=731218',
profit_type: 'PPS+',
profit_perc: 0 },
{ pool_name: 'F2Pool',
url_link: 'https://www.f2pool.com',
profit_type: 'PPS+',
profit_perc: 0.03 } ] },
{ Manufacturer: 'Jasminer',
Model: 'X4',
Release: 'November 2021',
'Noise level': '75db',
'Fan(s)': '4',
'Power(w)': 1200,
Interface: 'Ethernet',
Memory: '5G',
Temperature: '5 - 40 °C',
Humidity: '5 - 95 %',
coins:
[ 'Ubiq',
'Ethereum',
'Ethereum Classic',
'Musicoin',
'Pirl',
'EtherGem',
'Callisto',
'QuarkChain' ],
available_stores:
[ { store_name: 'Safety Miner',
url: 'https://www.safetyminer.net/product-page/jasminer-x4-2-6gh-1200w?ref=3yrntphlqn',
price: '$20,163.18',
country: 'United Kingdom',
stock: 'Out of stock',
isFreeShipping: false },
{ store_name: 'Jingle Mining',
url: 'https://www.jinglemining.com/products/jasminer-x4-etchash-server?ref=3yrntphlqn&variant=42041025233122',
price: '$20,499.00',
country: 'China',
stock: 'Pre-order(Jun 2022)',
isFreeShipping: false },
{ store_name: 'ViperaTech',
url: 'https://www.viperatech.com/product/jasminer-x4-etchash-server/?ref=585',
price: '$21,000.00',
country: 'Canada',
stock: 'In stock',
isFreeShipping: false },
{ store_name: 'AKMiner',
url: 'https://akminer.com/all-products/jasminer-x4-etchash-server-jan-shipment?wpam_id=1',
price: '$23,999.00',
country: 'China',
stock: 'Used',
isFreeShipping: false },
{ store_name: 'BT-Miners',
url: 'https://bt-miners.com/collections/eth-miners/products/jasminer-x4-etc-eth-5g-miner-2500mh-s-mine-eth-till-june-2022?ref=3yrntphlqn&ref=3yrntphlqn&variant=42969029378235',
price: '$24,459.00',
country: 'United States',
stock: 'Used',
isFreeShipping: false },
{ store_name: 'NHASH',
url: 'https://www.nhash.net/miners/99141979488657408?ref=3yrntphlqn',
price: '$24,999.00',
country: 'Hong Kong',
stock: 'Pre-order(May 2022)',
isFreeShipping: false },
{ store_name: 'CoinMining Central',
url: 'https://coinminingcentral.com/collections/jasminer/products/jasminer-x4-eth-ethereum-miner-2500mh?ref=uybdgyQD',
price: '$29,674.99',
country: 'United Kingdom',
stock: 'Pre-order(Jul 2022)',
isFreeShipping: false },
{ store_name: 'Bitcoin Merch',
url: 'https://bitcoinmerch.com/products/jasminer-x4-2-5-gh-s-ethereum-miner?aff=2',
price: '$51,999.99',
country: 'United States',
stock: 'In stock(30 \ndays\n)',
isFreeShipping: false } ],
Algorithm_and_power:
[ { Algorithm_name: 'EtHash',
'hashrate(H/hour) ': 2500000000,
'power_consumption(W)': 1200 },
{ Algorithm_name: 'EtHashETC',
'hashrate(H/hour) ': 2500000000,
'power_consumption(W)': 1200 } ],
available_mining_pools:
[ { pool_name: 'Poolin',
url_link: 'https://www.poolin.com',
profit_type: 'FPPS',
profit_perc: 'FPPS' },
{ pool_name: 'SparkPool',
url_link: 'https://www.sparkpool.com/',
profit_type: 'PPS',
profit_perc: 0.01 },
{ pool_name: 'Ethermine',
url_link: 'https://ethermine.org',
profit_type: 'PPLNS',
profit_perc: 0.01 },
{ pool_name: 'ViaBTC',
url_link: 'https://pool.viabtc.com?refer=731218',
profit_type: 'PPS+',
profit_perc: 0 },
{ pool_name: 'F2Pool',
url_link: 'https://www.f2pool.com',
profit_type: 'PPS+',
profit_perc: 0.03 } ] },
I have this collection in my mongodb database, and when I query data from it, like for example .find("data.Manufacturer":"iPollo") because its nested documents, it returns for me the entire document, is there any way where I could return only the object from the array without like hardcoding it (getting the entire data liste and iterate through it to find the query I am searching for)
One option is using an aggregation pipeline:
db.collection.aggregate([
{$match: {"data.Manufacturer": "iPollo"}},
{$set: {
data: {
$filter: {
input: "$data",
cond: {$eq: ["$$this.Manufacturer", "iPollo"]}
}
}
}
},
{$replaceRoot: {newRoot: {$first: "$data"}}}
])
See how it works on the playground example
I am not sure how to phrase this question properly but basically I have an "Order" Schema and each order model contains an array of product objects created using "Product" Schema
When I create an order, my req.body is this
body: {
orderItems: [ [Object] ],
shippingAddress: {
fullName: '123',
address: '1231',
city: '123',
postalCode: '123',
country: '123'
},
shippingPrice: 0,
paymentMethod: 'Stripe',
itemsPrice: 338,
totalPrice: 338
},
If I log req.body.orderItems, I can see each product object printed
{
_id: new ObjectId("62d51a3895cad3ca283302f3"),
name: 'Christmas Cake',
slug: 'christmas-cake',
image: '/images/cake.jpg',
shop: 'Custom Cakes',
category: 'food',
description: 'Custom baked christmas cake, pre-order needed.',
price: 70,
stock: 1,
rating: 3,
numReviews: 2,
__v: 2,
createdAt: 2022-07-18T08:30:48.931Z,
updatedAt: 2022-07-20T03:03:00.592Z,
}
{
_id: new ObjectId("62d7a8c126dcacfc13055e3d"),
name: 'cake',
slug: 'cake',
image: '/images/cake.jpg',
shop: 'Custom Cakes',
category: 'food',
description: 'cake',
price: 15,
stock: 2,
rating: 0,
numReviews: 0,
user: { _id: new ObjectId("62d51d57c08cd7e6675e8d45")},
reviews: [],
createdAt: 2022-07-20T07:03:29.372Z,
updatedAt: 2022-07-20T07:03:59.315Z,
__v: 0
}
But I am unable to obtain the 'shop' field. req.body.orderItems.shop returns undefined
I want to use by default all the datas from rowData, I do not want use specific values. Do you know how to unify columnDefs for both examples?
1st example:
columnDefs = [
{headerName: 'make', field: 'make' },
{headerName: 'model', field: 'model' },
{headerName: 'price', field: 'price'}
];
rowData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 }
];
2nd example:
columnDefs = [
{headerName: 'name', field: 'name' },
{headerName: 'phone', field: 'phone' },
];
rowData = [
{ name: 'Manuel', phone: 35000 },
{ name: 'Maria', phone: 32000 },
{ name: 'John', phone: 72000 }
];
I have one idea, but dont exactly know if it is more elegant.
var columnDefs = [
{ headerName: "make", field: "make" },
{ headerName: "model", field: "model" },
{ headerName: "price", field: "price" }
];
var rowData = [
{ make: "Toyota", model: "Celica", price: 35000 },
{ make: "Ford", model: "Mondeo", price: 32000 },
{ make: "Porsche", model: "Boxter", price: 72000 }
];
genColums() {
let columsDef = [];
for (var prop in rowData[0]) {
columsDef.push({
headerName: prop,
field: prop
});
}
console.log(columsDef);
}
this.genColums();
PS. this work, if all data same, in each object
I want to add a new element in AG Grid. I have a following model:
export class PersonModel {
cars: CarModel[];
}
The AG Grid has as rowData the array Cars of my model. But this array is not Observable. Now I want to add a new car when I click a button:
<button type="button" (click)="onClickCreateCar()">
And in my viewmodel:
onClickCreateCar() {
var emptyCar = new CarModel();
this.person.cars.push(emptyCar);
}
I can not see the new row in the grid because the array Cars is not observable. It is ok because the property of a model should not be observable. How do you fix the problem?
My AG-Grid definition:
<ag-grid-angular class="ag-theme-fresh" *ngIf="person" style="height: 100%; width: 100%;" [gridOptions]="gridOptions" [rowData]="person.cars" [columnDefs]="columnDefs">
For insert a new row into ag-grid you shouldn't use the rowData directly it will create\override existing object and all states would be reset, and anyway, there is a method for it setRowData(rows)
But I'd recommend to use updateRowData(transaction):
updateRowData(transaction) Update row data into the grid. Pass a transaction object with lists for add, remove and update.
As example:
gridApi.updateRowData({add: newRows});
for angular:
set id for html - selector (#agGrid in this example):
<ag-grid-angular
#agGrid
style="width: 650px; height: 500px;"
class="ag-theme-balham"
[rowData]="rowData"
[columnDefs]="columnDefs"
>
</ag-grid-angular>
and then define the viewchild with this id, import AgGridAngular like shown below, then you can use the ag-grid api in Angular
import {Component, OnInit, ViewChild} from '#angular/core';
import { AgGridAngular } from 'ag-grid-angular';
#Component({
selector: 'app-angular-handsometable',
templateUrl: './angular-handsometable.component.html',
styleUrls: ['./angular-handsometable.component.scss']
})
export class AngularHandsometableComponent implements OnInit {
#ViewChild('agGrid') agGrid: AgGridAngular;
columnDefs = [
{headerName: 'Make', field: 'make', sortable: true, filter: true, editable: true },
{headerName: 'Model', field: 'model', sortable: true, filter: true, editable: true },
{headerName: 'Price', field: 'price', sortable: true, filter: true, editable: true }
];
rowData = [
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 },
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 },
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 },
{ make: 'Toyota', model: 'Celica', price: 35000 },
{ make: 'Ford', model: 'Mondeo', price: 32000 },
{ make: 'Porsche', model: 'Boxter', price: 72000 }
];
constructor() { }
ngOnInit() {
}
save() {
console.log( 'Save', this.rowData );
}
addRow() {
this.agGrid.api.updateRowData({
add: [{ make: '', model: '', price: 0 }]
});
}
}
Make sure your rowData array is getting updated with the new object you added and if its getting updated and its just a question of updating the grid view, you can explicitly call the refresh API's of the grid.
https://www.ag-grid.com/javascript-grid-api/#refresh
I visited ag-grid documentation and got rowData is simple array. If ag-grid not refreshing your dom then may be they want a fresh array. You can do like this:
this.person.cars = [this.person.cars.slice(0), yourNewCarObj];
It's like this (but start from 1):
Please note the number is for the row element of grid instead of row data of the source. So the number shown in the first cell of each rows should indicate the position of the current row (which starts from 1 for the first row) regardless the row data and the sorting criteria.
Update: The result is like this: https://jsfiddle.net/wp6o350z/
<script src="https://unpkg.com/ag-grid/dist/ag-grid.min.noStyle.js"></script>
<link rel="stylesheet" href="https://unpkg.com/ag-grid/dist/styles/ag-grid.css">
<link rel="stylesheet" href="https://unpkg.com/ag-grid/dist/styles/ag-theme-balham.css">
<div id="myGrid" style="height: 200px;width:500px;" class="ag-theme-balham"></div>
<script type="text/javascript" charset="utf-8">
// specify the columns
var columnDefs = [
{headerName: "#", field: "row", width: 30 },
{headerName: "Make", field: "make", width: 100 },
{headerName: "Model", field: "model", width: 100},
{headerName: "Price", field: "price", width: 100}
];
// specify the data
var rowData = [
{row: 1, make: "Toyota", model: "Celica", price: 35000},
{row: 2, make: "Ford", model: "Mondeo", price: 32000},
{row: 3, make: "Porsche", model: "Boxter", price: 72000},
{row: 4, make: "Toyota", model: "Celica", price: 35000},
{row: 5, make: "Ford", model: "Mondeo", price: 32000},
{row: 6, make: "Porsche", model: "Boxter", price: 72000},
{row: 7, make: "Toyota", model: "Celica", price: 35000},
{row: 8, make: "Ford", model: "Mondeo", price: 32000},
{row: 9, make: "Porsche", model: "Boxter", price: 72000}
];
// let the grid know which columns and what data to use
var gridOptions = {
columnDefs: columnDefs,
rowData: rowData,
};
// lookup the container we want the Grid to use
var eGridDiv = document.querySelector('#myGrid');
// create the grid passing in the div to use together with the columns & data we want to use
new agGrid.Grid(eGridDiv, gridOptions);
</script>
The problems in this sample are:
The row number is defined in the data, which is not supported in real case. Maintaining a row is difficult and slow since inserting from the beginning will need to update many rows.
Since the row number is defined in the data, after sorting you won't see the row number is randomized. I still want to see the row number start from 1 from the beginning.
Basically it's easier to be part of the grid feature, and many other grids (not limited to JS grids) support this. I'm wondering if it's easy to do it in with ag-grid.
Ag-grid now has a "valueGetter" for cells that takes an expression, so you can just use
columnDefs: [
{
headerName: "Row",
valueGetter: "node.rowIndex + 1"
},
(other columns)
]
In order to have it refresh after sorting, you need to call refreshCells:
onSortChanged(e: AgGridEvent) {
e.api.refreshCells();
}
If you are filtering, you would do the same thing on the 'filterChanged' event.
One way that we can use is:
create a custom component that implements "ICellRendererAngularComp" interface
refer to https://www.ag-grid.com/javascript-grid-cell-rendering-components/#example-rendering-using-angular-components
and implements agInit method like below:
import { ICellRendererAngularComp } from 'ag-grid-angular';
import { Component } from '#angular/core';
#Component({
selector: 'app-ag-grid-row-number',
templateUrl: './ag-grid-row-number.component.html',
styleUrls: ['./ag-grid-row-number.component.scss']
})
export class AgGridRowNumberComponent implements ICellRendererAngularComp {
rowNumber: number;
refresh(params: any): boolean {
return true;
}
agInit(params: import('ag-grid-community').ICellRendererParams): void {
this.rowNumber = params.rowIndex + 1;
}
afterGuiAttached?(params?: import('ag-grid-community').IAfterGuiAttachedParams): void {
}
}
In your view:
{{ rowNumber }}
finally in your list component:
public columnDefs = [
{headerName: 'row number', cellRendererFramework: AgGridRowNumberComponent},
... ]