KendoUI for Angular2 DataQuery toODataString not generating $filter in querystring

731 views Asked by At

The documentation for KendoUI for Angular2 mentions that the toODataString method converts the provided state object to an oData v4 compatible string.

The structure of said state object is defined here.

I have set up a KendoUI for Angular2 grid with data-binding and server-side paging as described here, which is working fine.

So now I want to add a filter object to that state, and I'm using the following code to do so:

private filter: CompositeFilterDescriptor;

public applyFilters(): void {
    this.filter = {
        logic: "and",
        filters: []
    };
    this.skip = 0;
    this.sort = [];

    if (this.customerNameFilter) {
        let fd: FilterDescriptor = {
            field: "name",
            operator: "contains",
            value: this.customerNameFilter,
            ignoreCase: true
        }
        this.filter.filters.push(fd);
    }
    this.service.query({ skip: this.skip, take: this.pageSize, filter: this.filter });
}

The service.query method then calls the toODataString method, and returns the following querystring (note the double ampersand as if it tried to insert something that evaluated to null):

$skip=0&$top=15&&$count=true

Here is a screenshot of the debugger showing the structure of the filterDescriptor instance passed in to the toODataString method. Please advise what I am doing wrong here?

debugger showing FilterDescriptor object

1

There are 1 answers

0
Shawn de Wet On

Turns out it's not supported in the current beta of the toODataString method. I looked into it's source and found there is no handling of the filter property of the state that is passed in to it.

So I rolled my own filterSerializer to append to the querystring:

private fetch(tableName: string, state: any, filter: CompositeFilterDescriptor): Observable<GridDataResult> {
    const queryStr = `${toODataString(state) + this.serializeFilter(filter)}&$count=true`;
    return this.http
        .get(`${this.BASE_URL}${tableName}?${queryStr}`)
        .map(response => response.json())
        .map(response => (<GridDataResult>{
            data: response.value,
            total: parseInt(response["@odata.count"], 10)
        }));
}

private serializeFilter(filter: CompositeFilterDescriptor): string {
    if (filter === null)
        return "";
    var filterString = "&$filter=";
    var filters = filter.filters.map(function (fd: FilterDescriptor) {
        switch (fd.operator) {
            case "contains":
                return "contains(" + fd.field + ", '" + fd.value + "')";
            case "eq":
                return fd.field + " eq '" + fd.value + "'";
        }            
    })
        .join(" " + filter.logic + " ");
    filterString += filters;
    return filterString;
}