Giter VIP home page Giter VIP logo

ag-grid-odata's People

Contributors

dependabot[bot] avatar senyamur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

ag-grid-odata's Issues

Broken filtering with ag-grid@25

Hello Semen,

I've just noticed one more critical thing that stopped to work in our project after upgrade of ag-grid.
It is filtering. No calls to API when change filtering settings.

Here is fork for you with customer field enabled to filter:

https://codesandbox.io/s/ag-grid-server-side-row-model-sample-forked-b0p8b

With ag-grid@25 and 1.0.20/1.0.19 ag-grid-odata open Filters tab and try to filter Customers. No any call to API.

It to switch to ag-grid@24 -- all works - request to API is performed.

It would be great if you find time to fix this.

Thanks in advance.

Unable to group and expand data fields

Steps to Reproduce:

Create a dataset with date fields.
Configure Ag-Grid to display the dataset, allowing grouping by date fields.
Attempt to group the data by date.
Group works as expected.
Expand grouped row.
Odata uses date to filter value as string (not a date type)

Expected Behavior:
Odata filter uses date as intended.
https://odatasampletest.azurewebsites.net/odata/Heroes?$count=true&$top=100&$filter=AddedOn eq 2024-03-28
Actual Behavior:
When expand a grouped column (by date), Odata sends a request as grouped Date is a type of string. this triggers a backend error.
https://odatasampletest.azurewebsites.net/odata/Heroes?$count=true&$top=100&$filter=AddedOn eq '2024-03-28'

I have attached a repo. for the following issue.
Steps:

  1. Group by AddedOn column
  2. Expand Date column
    https://codesandbox.io/p/sandbox/stupefied-leaf-pycscc

Set isCaseSensitiveStringFilter true/false per column

So I hit another "issue" or what to call it with the plugin and how it creates the ODATA filter string.

I do realize that perhaps this issue could be solved by configuring the backend, but I'm raising the issue anyway to perhaps add more flexibility to the package somewhere down the line.

Another thing that would add more flexibility would be the possibility to on a per-column setting set if it should be case sensitive or not. Ag-Grid has this setting for text (https://www.ag-grid.com/react-grid/filter-text/) and the caseSensitive setting.

For regular text filters that searches text strings in the ODATA it works just fine with isCaseSensitiveStringFilter set to false (or omitted). However for agSetColumnFilter that ODATA filters on Enums it does not.

Setting isCaseSensitiveStringFilter to true will make agSetColumnFilter work as expected, but will on the other hand force case sensitivity on fields that are simple text searches.

An example:
Column A contains colors as strings (White, Black, Green etc.) that I can search for using the regular agTextColumnFilter. It will by default return all matches if i type "gre" and will be case insensitive as well. All is good.

Column B however contains Color Code enums instead. Lets say 1000 = White, 2000 = Black, 3000 = Green and will display the codes (1000, 2000, 3000) and that is also what I filter on. The column is set to be a agSetColumnFilter with the values 1000, 2000, 3000 as possible filter values.

If I set isCaseSensitiveStringFilter: true it works and the ODATA query looks like this:
[odata-address]?$count=true&$top=250&$filter=ColorCode%20in%20(%271000%27) and returns rows as expected.

If I set it to false the request looks like this:
[odata-address]?$count=true&$top=250&$filter=tolower(ColorCode)%20in%20(%271900%27)

And the ODATA address returns 400 (bad request)

{
    "error": {
        "code": "",
        "message": "The query specified in the URI is not valid. No function signature for the function with name 'tolower' matches the specified arguments. The function signatures considered are: tolower(Edm.String Nullable=true).",
        "details": [],
        "innererror": {
            "message": "No function signature for the function with name 'tolower' matches the specified arguments. The function signatures considered are: tolower(Edm.String Nullable=true).",
            "type": "Microsoft.OData.ODataException",
            "stacktrace": "
            at Microsoft.OData.UriParser.FunctionCallBinder.MatchSignatureToUriFunction(String functionCallToken, SingleValueNode[] argumentNodes, IList`1 nameSignatures)\n
            at Microsoft.OData.UriParser.FunctionCallBinder.BindAsUriFunction(FunctionCallToken functionCallToken, List`1 argumentNodes)\n
            at Microsoft.OData.UriParser.FunctionCallBinder.BindFunctionCall(FunctionCallToken functionCallToken)\n
            at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\n
            at Microsoft.OData.UriParser.MetadataBinder.<BindIn>b__22_0(QueryToken queryToken)\n
            at Microsoft.OData.UriParser.InBinder.GetSingleValueOperandFromToken(QueryToken queryToken)\n
            at Microsoft.OData.UriParser.InBinder.BindInOperator(InToken inToken, BindingState state)\n
            at Microsoft.OData.UriParser.MetadataBinder.BindIn(InToken inToken)\n
            at Microsoft.OData.UriParser.MetadataBinder.Bind(QueryToken token)\n
            at Microsoft.OData.UriParser.FilterBinder.BindFilter(QueryToken filter)\n
            at Microsoft.OData.UriParser.ODataQueryOptionParser.ParseFilter()\n
            at Microsoft.AspNetCore.OData.Query.FilterQueryOption.get_FilterClause()\n
            at Microsoft.AspNetCore.OData.Query.Validator.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings)\n
            at Microsoft.AspNetCore.OData.Query.Validator.ODataQueryValidator.Validate(ODataQueryOptions options, ODataValidationSettings validationSettings)\n
            at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.ValidateQuery(HttpRequest request, ODataQueryOptions queryOptions)\n
            at Microsoft.AspNetCore.OData.Query.EnableQueryAttribute.OnActionExecuting(ActionExecutingContext actionExecutingContext)"
        }
    }
}

AND/OR filters don't work

Hi! @SenyaMur

Thank you for this great little package! It seems to work like magic in combination with ASP.NET and Entity Framework.

I found a bug though. You can quickly repro it with the demo by adding filter="agNumberColumnFilter" to Price and filtering it with AND/OR (for example less than 200 and greater than 50).

The error is:

TypeError
me.odataOperator[col.type] is not a function

and also:

ReferenceError
keyEventHandler is not defined

There is an error with your odata provider

Hi there is this error
ERROR TypeError: Cannot read properties of undefined (reading 'setSecondaryColumns') at OdataProvider.getRows (OdataProvider.js:720)
Angular Version 13
ag-grid version is 26.2.0

Thanks

Queries with null as value

Hello again,

So I've hit another issue that I'd like to discuss.

  • I have column that is typed as NVARCHAR, null in the SQL database
  • I set the column as set filter type in ag grid and supply it with unique values from the database (A, B, C, D, E, null)
  • In Ag-Grid they show up just fine in the filter for the column like so:
    • (Select All)
    • (Blanks) [this is the one that is null]
    • C
    • D
    • E
    • K
  • I can filter just fine on anything that is an actual value or if I use (Select All).

The ODATA query URL then looks like this:
$filter=tolower(ColumnName)%20in%20(%27c%27,%27d%27,%27e%27,%27k%27)
(unencoded: $filter=tolower(ColumnName) in ('c','d','e','k'))
and results are returned as expected.

Using the (Blanks) value however, where the value actually is NULL will give 0 results. This is because the query looks like this:
$filter=tolower(GearboxCode)%20in%20(%27null%27)
(unencoded: $filter=tolower(GearboxCode) in ('null'))
but would need to look like this:
$filter=tolower(GearboxCode)%20in%20(null)
(unencoded: $filter=tolower(GearboxCode) in (null))
(note the lack of '' [encoded as %27] around the null value).

Is there an easy way to solve this and have the query work as I'd need above?

Could not resolve dependency

Hello my friend
There is a dependency problem in your package, please check and fix this

Could not resolve dependency:
npm ERR! peer ag-grid-community@"^26.2.1" from [email protected]
npm ERR! node_modules/ag-grid-odata
npm ERR! ag-grid-odata@"^1.0.29" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: [email protected]
npm ERR! node_modules/ag-grid-community
npm ERR! peer ag-grid-community@"^26.2.1" from [email protected]
npm ERR! node_modules/ag-grid-odata
npm ERR! ag-grid-odata@"^1.0.29" from the root project

beforeRequest not calling functions on subsequent runs?

Hello again!

I have expanded my implementation of the ag-grid-odata package in my solution.

I do the following:

const onGridReady = async (event: GridReadyEvent) => {

    event.api.setServerSideDatasource(
        new OdataProvider({
            callApi: (options) => fetch(`[backendAddress]${options}`, {
                headers: {
                    'Content-type': 'application/json',
                    Accept: 'application/json',
                },
            })
                .then((resp) => resp.json())
                .then((resp) => {
                    // other code removed for brevity
                    return resp;
                }),
            beforeRequest: (query, provider, request) => {
                query.filter = createExpandedOdataQuery();
                console.log(query);
            },
            isCaseSensitiveStringFilter: false,
            caseSensitiveColumns: viewSetting ? viewSetting.enumColumns : undefined,
        }) as unknown as IServerSideDatasource,
    );
};

and everything works as expected for the built in filters (and works great with your update the other day as well with caseSensitiveColumns).

However I do run a function on beforeRequest as you can see, createExpandedOdataQuery(). This function returns a string array with extra odata filters built from an external input field that I attempt to use a more free form text search field. (I take the input string and creates a supplementary ODATA string out of it).

However it does not seem to actually use any state strings or updated variants of these.

Just to make a test I did the following:
I setup the provider as above, in beforeRequest I simply added a console.log() for a state (const [test, setTest] = React.useState<string>();)

and then whenever I recieve the state that a search should be executed I set the test-state to be a different string, but that is never picked up. If I check the state of test it is indeed updated. And it does not seem to be an async issue either, because subsequent searches still does not log the updated string from the test state.

create state, set it to "foo" as default, then set it to "bar". It is indeed logged with its updated value.

    const [test, setTest] = React.useState<string>('foo');

    React.useEffect(() => {
        if (search.performSearch) {
            setTest('bar');
        }
    }, [search.performSearch]);

    console.log(test); // returns "foo" on first render, returns "bar" efter recieving search.performSearch)

But in here its always logged as "foo" no matter how many times I execute things.

  beforeRequest: (query, provider, request) => {
    console.log(test);
  },

Is this by design or am I missing something?

I did some experiments with setting the serverSideDataSource in React.useEffect, but then it will execute two serverSideDataSource requests, one that was registered already and then the new one that is added in my useEffect :(

Edit:
Expanding a bit on the above.

I have tried the following as well, making sure that the state is set before I trigger a onFilterChanged in the useEffect. The flow works as expected with were it triggers the onFilterChanged etc. beforeRequest still does not fetches the updated value from the string though :(

const [newString, setNewString] = React.useState<Array<string>>();

React.useEffect(() => {
    const createExpandedOdataQuery = () => {
        // code for creating ODATA query
        return odataQueryString !== '' ? [`${odataQueryString}`] : undefined;
    };
    if (search.performSearch) {
        setNewString(createExpandedOdataQuery());
    }
}, [agGridApi.gridApi, search.performSearch, search.searchString]);

React.useEffect(() => {
    if (newString) {
        agGridApi.gridApi?.onFilterChanged();
    }
}, [agGridApi.gridApi, newString]);

const onGridReady = async (event: GridReadyEvent) => {
    event.api.setServerSideDatasource(
        new OdataProvider({
            ...,
            beforeRequest: (query, provider, request) => {
                console.log(newString);
                query.filter = newString;
            },
            isCaseSensitiveStringFilter: false,
            caseSensitiveColumns: viewSetting ? viewSetting.enumColumns : undefined,
        }) as unknown as IServerSideDatasource,
    );
};

typings mismatch

Is it possible the npm package is referencing older version of ag-grid?
I'm finding some errors, I think maybe ag-grid changed how to reference it.

e.g.

Error: node_modules/ag-grid-odata/build/OdataProvider.d.ts:2:10 - error TS2305: Module '"@ag-grid-enterprise/all-modules"' has no exported member 'IServerSideGetRowsParams'.

and for example, in the types.d.ts this does not compile:
import { ColumnVO } from '@ag-grid-community/all-modules';
but this is ok:
import { ColumnVO } from 'ag-grid-community';

Grouping issue

The issue is related to object we work with if we receive more rows than we expect to get:

me.callApi(query + '/aggregate($count as count)').then(function (y) {
count_1 = y[0].count;
params.successCallback(values_1, count_1);
});

To fix it, the code in line 498 should be the following:
count_1 = y.value[0].count;

Please can you check the issue on your side and fix it.
Regards and thank you.

Wrong Request if using Browser Picker in Ag-grid

if select date from ag grid picker(browser picker), this library adds orphan time

AR: $filter: StartDate eq 2020-07-15 00:00:00T00:00:00.000Z
ER: $filter: StartDate eq 2020-07-15T00:00:00.000Z

index.es.js=>184 Line of Code. Can it somehow configured? No special settings of Ag Grid

Crash when query first and undefined count

My case is:

  1. Load first page from server, it did with $count (
    https://github.com/SenyaMur/ag-grid-odata/blob/master/src/OdataProvider.ts#L946)
    This step is ok
  2. Load second page from server (after scrol grid), it did without $count
    This step is ok
  3. And after without scrol i do refresh (with aggrid purgeServerSideCache)
    This step is crashed (near this line https://github.com/SenyaMur/ag-grid-odata/blob/master/src/OdataProvider.ts#L704)
    I think it because of second page loaded firstly and without $count and aggrid crashed.

I did workaround
new OdataProvider({
callApi: options => {
if (!options.includes('$count=')) options = options + "&$count=true"
...

But I think it is not good.

Expansion depth bigger then 2 not working

When I try to use column with name like 'Requirement.Customer.Name' with expansion depth bigger then 2 it is not working.
I think it is because of you use js function replace (single replace only) instead of replaceAll when you change "." to "/"
Could you repair it?

Sorting does not work with groups (Server side)

There is no parameter to sort the grouped columns.
I am using the Server Side mode.

Steps to replicate:

  1. I am grouping the grid by some column
  2. I am changing the sorting of the group column by clicking on it.

Expected Result: get?$top=100&$apply=groupby((Column_Name)),aggregate($count%20as%20childCount))&$orderBy=childCount
Actual Result: get?$top=100&$apply=groupby((Column_Name)),aggregate($count%20as%20childCount))

AG Grid 28.0.x

Hi my friend
In the new ag-grid update, a number of methods have been renamed. Thank you for checking.

WARNING:
=> AG Grid: since version 28.0.x setSecondaryColumns has been renamed, please use setPivotResultColumns instead

AG Grid Changelog

Storybook failed on run

On run storybook receive error:

ERROR in ./node_modules/ag-grid-odata/build/index.js 1:9
Module parse failed: Unexpected token (1:9)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> export * as types from './types';
| export { OdataProvider as default, OdataServerSideProvider, OdataProviderClient } from './OdataProvider';
| //# sourceMappingURL=index.js.map
......

Demo not working?

Demo link seems to crash transpiling.
Also, any chance there is an angular sample?

Proposed code improvements of the library

Hi,

While looking at the code I took some notes that I thought I'd add as proposed improvements. They are not at all related to functionality (still working great!), but rather to ease development and reading for users of the package.

  • OdataProvider.ts contains a comment in russian (?) on line 798. Could this be updated to be in english, like the other comments in the code?
  • Could smaller functions be separated into their own files and imported, to keep the length of the OdataProvider.ts shorter?
    • escapeRegExp
    • replaceAll
  • Could interfaces and classes be separated into their own files as well?

I might do a PR if I have the time and get around to it. :)

Edit: I forked and created a branch here: https://github.com/kosmiq/ag-grid-odata/tree/split-into-modules. It's just a proposal, so I'll let you decide what to do with it. :)

Usage with TypeScript issue

First off, I can not thank you enough for creating and publishing this package. It just saved me a bunch of hours and implementation and testing. It seems to work really well, and was easy to implement and manages filter in a way that I do really appreciate and like as a baseline.

We are in a TypeScript (React) project, and using the examples as they are produces typescript errors:
image

I did not really look into the types, but it is solvable by doing typecasting as below:
image

Preferably the OdataProvider would export itself with a type corresponding to what is wanted by setServerSideDatasource in a typescript setup.

This is mostly to raise awareness of the issue and potentially help others that might hit the same snag.

Server Side Pagaination

Hi SenyaMur,
I've been using your OData plugin for ag-grid for a small 4 row table, which is great . I am having an issue with server side pagination (aka, loads each page from an api call when clicking on a new page) and was wondering what I'm doing incorrectly. Given below...

onGridReady(params: GridReadyEvent) {
params.api.setServerSideDatasource(
new OdataServerSideProvider({
callApi: (options) =>
axiosApp
.get(/odata/v1/Data${options})
.then((resp) => {
return resp.data;
}),
beforeRequest: (
query: OdataQueryOptions,
provider: OdataProvider,
request: IGetRowsParams | IServerSideGetRowsRequest
) => {
query.select = new Array();
this.state.columnDefs.forEach((column, index) => {
query.select?.push(column.field);
});

      // NOTE: I do this to get any pagination going otherwise all the items are returned
      request.startRow = params.api.paginationGetCurrentPage();
      request.endRow = params.api.paginationGetPageSize();
    },
    afterLoadData: (options, rowData, totalCount) => {    // NOTE: totalCount is correct at 6
      if (options.skip === 0 && rowData.length > 0) {
        params.api.sizeColumnsToFit();
      }
    },
  })
);

}

I get below in return which is correct from the backend but the total count for the pagination is 4 in the table and I can't get to the next two items. In afterLoadData totalCount is correct at 6. Also (see NOTE) the only way I can get pagination in the url is to do the below by hand. Does the plugin support server side pagination (if I return everything the pagination is fine)?

// See Note: above
request.startRow = params.api.paginationGetCurrentPage();
request.endRow = params.api.paginationGetPageSize();

{
"@odata.context": "https://localhost:5001/odata/v1/$metadata#Data(Name,Description,TimeFrame,Id)",
"@odata.count": 6,
"value": [
{
"Name": "Name1",
},
{
"Name": "Name2",
},
{
"Name": "Name3",
},
{
"Name": "Name4",
}
]
}

Pivot mode issue with latest ag-grid

Hello Semen,
First of all - thank you for this library! Seems that it is the only one odata client for ag-grid.
Recently after upgrade ag-grid to the latest version I faced to the problem in pivot mode. Here is a fork:
https://codesandbox.io/s/ag-grid-server-side-row-model-sample-forked-q9z15

Steps to reproduce:

  1. Activate pivot mode
  2. Move "Customer" to Row groups, "Amount" to Values, "Order ID" to Column Labels.

The error appears:

Cannot read property 'blocks' of undefined
OdataProvider.eval
https://q9z15.csb.app/node_modules/ag-grid-odata/build/index.es.js:529:83
step
https://q9z15.csb.app/node_modules/ag-grid-odata/build/index.es.js:110:17

Could you please take a look?

Sorted groups issue on sorting of column

To replicate use the Server-Side model

Steps to replicate:

  1. Group data by some column
  2. Apply the sorting to group by clicking the label of the Group column
  3. Open one of collapsed groups
  4. Try to sort by any different field

Expected result:
The data is sorted, sorting of groups remains the same.

Actual Result:
Group is collapsed, group column is not sorted.

Applicable to the case when 2 or more groups are opened.

Pagination Issue

There is no clue for handling pagination in ag-grid on serverside. When the row data is less than the expected paginationPageSize, the next button should be disabled because there is no more data.

For example the paginationPageSize = 10 and the rowData.length = 3. The pagination should be stopped.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.