0

This ngrx/data API has method:

getWithQuery(queryParams: string | QueryParams, options?: EntityActionOptions): Observable<T[]>

To retreive data from the data source we can, in a simple form, use:

const criteria = {
  id: 'A001'
}
this.menuItemsService.getWithQuery(criteria);

This is clear and works fine returning a data subset.

Now, how will we get data subset with the same method under multiple criteria?

For example something like:

const criteria = {
    id: 'A001' or 'J003' or 'K008',
    year: 2001 or 2007
}
this.menuItemsService.getWithQuery(criteria);
Felix
  • 1,662
  • 2
  • 18
  • 37

1 Answers1

0

For this type of criteria, you will have to implement your own logic in the backend. I don't know what you are using for your backend but in my case is SQL... so what I did is I created a custom query param called "q" and then used custom query text like this:

const queryParams = "id_contains_A0001_OR_id_contians_J003_OR_id_contains_K008";
const query = `q=${encodeURIComponent(queryParams)}`;
this.menuItemsService.getWithQuery({
    q: query
});

Then on the backend, I simply parse whatever the "q" param has. For example, in my case, again, I am using SQL so the following suffice.

if(!!q){
  const queries = q.split(/_and_/).map(i=>i.toLowerCase());
  queries.forEach(stringQuery=>{
    const preliminarClauses: string[] = [];
    const containsOR = stringQuery.match(/_or_/);
    const allQueries: string[] = [];
    if(!!containsOR){
      allQueries.push(...stringQuery.split(/_or_/));
    } else {
      allQueries.push(stringQuery);
    }
    for(let i=0; i<allQueries.length; ++i){
      const query = allQueries[i];
      const operatorMatch = query.match(/!=|<>|<=|>=|_contains_|_in_|[<>=]/i);
      if(!!operatorMatch){
        let operator = operatorMatch[0];
        const parts = query.split(operator);
        const colName = "`" + parts[0] + "`";
        let value = parts[1];
        if(!!value){
          if(value === "null"){
            if(operator === "="){
              preliminarClauses.push(`(${colName} IS NULL OR $${colName} = '')`);
            } else if(["<>", "!="].includes(operator)){
              preliminarClauses.push(`(${colName} IS NOT NULL OR $${colName} != '')`);
            }
          } else if(operator === "_contains_"){
            preliminarClauses.push(`${colName} LIKE '%${value}%'`);
          } else if(operator === "_in_"){
            preliminarClauses.push(`${colName} IN (${value})}`);
          } else {
            const escVal = escapeStr(value);
            preliminarClauses.push(`${colName} ${operator} ${escVal}`);
          }
        }
      }
    }
    if(containsOR){
      whereClauses.push(`(${preliminarClauses.join(" OR ")})`)
    } else {
      whereClauses.push(...preliminarClauses);
    }
  });
}

The above is a code excerpt so you can get the idea.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Morfinismo
  • 4,985
  • 4
  • 19
  • 36