This is a migrated thread and some comments may be shown as answers.

DataSource - OData v4 filters - fix GUID and substring

5 Answers 639 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
Casimodo
Top achievements
Rank 1
Casimodo asked on 30 Jun 2015, 05:07 PM

Hi,

I'm using row filters in Kendo-grids with "odata-v4" specified on the data-sources. I'm writing here, because I'm not sure if this is a data-source issue or a grid issue. There are two filter scenarios where errors occur on the server side (ASP.NET MVC):

1) Kendo's current implementation still uses the old "substring" instead of the OData v4 "contains" expression. The server barks.

2) Since GUIDs are handled as strings, they are wrapped in single quotation marks. The server barks.

I'm using Kendo UI version 2015.2.624.

The following hack works around those issues. It would be great if those two scenarios could be fixed in the library.

 

fixODataV4FilterParameterMap = function (options) {
// This is needed for Kendo-grid's filters when using OData v4.
 
    // Call the default OData parameterMap.
    var result = kendo.data.transports.odata.parameterMap(options);
 
    if (result.$filter) {
         
        result.$filter = result.$filter.replace(/('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig, function (x) {
 
        // Remove the single quotation marks around the GUID (OData v4).
        return x.substring(1, x.length - 1);
        });
 
        // Replace "substring" with "contains" (OData v4)
        result.$filter = result.$filter.replace(/substringof\((.+),(.*?)\)/, "contains($2,$1)");
    }
    return result;
};

 

Regards,

Kasimier Buchcik

5 Answers, 1 is accepted

Sort by
0
Casimodo
Top achievements
Rank 1
answered on 30 Jun 2015, 06:32 PM

Just noticed that the above hack fails miserably for multiple substring expressions. E.g.:

"(substringof('10',Number) and substringof('abcg',Name))"
incorrectly becomes:
"(contains(Name,'10',Number) and substringof('abcg'))"

Does someone have a working strategy at hand here?

0
Casimodo
Top achievements
Rank 1
answered on 30 Jun 2015, 07:26 PM

Ok, this seems to work:

// Replace "substring" with "contains" (OData v4).
 
result.$filter = result.$filter.replace(/substringof\((.*?),(.*?)\)/, "contains($2,$1)");

0
Casimodo
Top achievements
Rank 1
answered on 30 Jun 2015, 07:32 PM

Nope, I forgot the "g" at end:

result.$filter = result.$filter.replace(/substringof\((.*?),(.*?)\)/g, "contains($2,$1)");

 

 

0
Casimodo
Top achievements
Rank 1
answered on 30 Jun 2015, 08:26 PM

While debugging in the data-source's code, I learned that there support for OData filter expressions was already implemented. One just has to enable it via parameterMap's argument "useVersionFour". This takes care of the "substring" -> "contains" issue. Only the fixup of the GUID string remains:

fixODataV4FilterParameterMap = function (data, type) {
    // This is needed for Kendo-grid's filters when using OData v4.
 
    // Call the default OData parameterMap.
    // NOTE: The last boolean parameter indicates that OData v4 is used.
    var result = kendo.data.transports.odata.parameterMap(data, type, true);
 
    if (result.$filter) {
 
        // Remove the single quotation marks around the GUID (OData v4).
        result.$filter = result.$filter.replace(/('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig, function (x) {               
            return x.substring(1, x.length - 1);
        });           
    }
    return result;
};

1
Casimodo
Top achievements
Rank 1
answered on 01 Jul 2015, 08:39 PM

The above is still not correct. One has to call the default OData V4 parameterMap (i.e. not the older OData parameterMap). Otherwise the $inlinecount will not be transformed to $count.

fixODataV4FilterParameterMap = function (data, type) {
    // This is needed for Kendo grid's filters when using OData v4.
 
    // Call the default OData V4 parameterMap. 
    var result = kendo.data.transports["odata-v4"].parameterMap(data, type);
 
    if (result.$filter) {
 
        // Remove the single quotation marks around the GUID (OData v4).
        result.$filter = result.$filter.replace(/('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}')/ig, function (x) {               
            return x.substring(1, x.length - 1);
        });           
    }
    return result;
};

 

EMEA
Top achievements
Rank 1
commented on 18 Oct 2022, 11:15 AM

I've just come across this issue too and the comments have been really useful to get a solution. My only tweak would be that the $filter is optional as the initial load may not have a filter set.

// Replace "substring" with "contains" (OData v4).
result.$filter = result.$filter?.replace(/substringof\((.*?),(.*?)\)/g, "contains($2,$1)");

Tags
Data Source
Asked by
Casimodo
Top achievements
Rank 1
Answers by
Casimodo
Top achievements
Rank 1
Share this question
or