Ngrx/data getWithQuery does not filter data according to the query I gave it

1k Views Asked by At

When I try to query for Approved Tags like so, it returns all entries not the approved ones

getAllApprovedTags(): Observable<Array<Tag>> {
    return this.tagsService.getWithQuery({tagStatus:'Approved'});
}

I have also tried the following

getAllApprovedTags(): Observable<Array<Tag>> {
        return this.tagsService.getWithQuery("tagStatus='Approved'");
}

And the following

getAllApprovedTags(): Observable<Array<Tag>> {
        return this.tagsService.getWithQuery("tagStatus=Approved");
}

I am using

Angular CLI: 11.0.1
Node: 10.19.0
OS: linux x64
NgRx/Data: 10.1.2

The back-end is

Loopback 4 and MongoDB

I have the following model

export class Tag {
  constructor(
    public id: string,
    public tagName: string,
    public tagDescription: string,
    public tagStatus: string,
    public createdDate: Date,
  ){ }
}

My entity config looks like the following

const entityMetadata: EntityMetadataMap = {
  Tag: {},
};

const pluralNames = {
  Tag: 'Tags',
};

export const entityConfig = {
  entityMetadata,
  pluralNames,
};

The service class looks like the following

@Injectable({
  providedIn: 'root'
})
export class TagsService  extends EntityCollectionServiceBase <Tag> {
  constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
    super('Tag', serviceElementsFactory);
   }
}

The data is as follows

Example Data

1

There are 1 best solutions below

1
On

getWithQuery simply adds query parameters to the endpoint URL:

/api/tags/?tagStatus=Approved

Even if the server is set up to handle this, it may not be what you're trying to do. More context is needed, but based off your question, it sounds like you're wanting to filter the collection of Tag entities down to those whose status is "Approved". If so, maybe you want filterFn (docs here):

const entityMetadata: EntityMetadataMap = {
  Tag: {
    filterFn: (tags: Tag[], status: TagStatus) => {
      return tags.filter(tag => tag.status === status);
    }
  },
};

And in your component:

getAllApprovedTags(): Observable<Array<Tag>> {
  this.tagService.setFilter(TestStatus.Approved); // or 'Approved' if you don't use an enum
  return this.tagsService.filteredEntities$;
}

However, from my understanding, any other places using that filter would also be changed, so it may be better for your use case to use a selector.

@Injectable({
  providedIn: 'root'
})
export class TagsService extends EntityCollectionServiceBase <Tag> {

  approvedTags$ = this.entities$.pipe(select(selectApprovedTags));

  constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
    super('Tag', serviceElementsFactory);
  }
}
// selectors

export const selectApprovedTags = createSelector(
  (tags) => tags,
  (tags: Tag[]) => tags.filter(tag => tag.status === TagStatus.Approved)
);

above selector implementation based on what I'm seeing in their demo