Search code examples
jsonangularangular-httpclient

Angular filter object


What's the best way to filter a json feed by a schema Angular? The reason I want to do this is to reduce the amount of data stored in an html page using the Transfer State API.

Ideal world I would like to define an Interface, and have only those fields used. But Interfaces are only used on compile-time, not runtime.

So currently have resorted to using:

export const FieldWhitelist = {
  'slug': true,
  'title': true,
  'type': true,
};

get(url): Observable<any> {
    return this.http.get(url).pipe(
      map(items => {
        if (typeof items === 'object') {
          Object.keys(items).forEach(field => {
            if (!FieldWhitelist[field]) {
              delete items[field];
            }
          });
        } else if (typeof items === 'array') {
          Object.keys(items).forEach(item => {
            Object.keys(items[item]).forEach(field => {
              if (!FieldWhitelist[field]) {
                delete items[item][field];
              }
            });
          });
        }
        return items;
      })
    );
}

This turns a json feed:

{
  'id': '12x324jh34',
  'metadata': 'sajhjksadhjkdsa'
  'slug': 'home',
  'title': 'Homepage',
  'type': 'page',
}

Into this:

{
  'slug': 'home',
  'title': 'Homepage',
  'type': 'page',
}

Is there a better way to recursively filter a json feed to match a schema?


Solution

  • You could define a class and map items in it, returning the class

    const obj = {
      'id': '12x324jh34',
      'metadata': 'sajhjksadhjkdsa',
      'slug': 'home',
      'title': 'Homepage',
      'type': 'page',
    }; 
    
    class Data {
      slug: string;
      title: string;
      type: string;
    
      constructor({slug, title, type}: {slug: string, title: string, type: string}) {
        this.slug = slug;
        this.title = title;
        this.type = type;
      }
    }
    
    console.log(new Data(obj));
    

    Also make sure to know what items is here, you shouldn't have need to check if it's an array or object IMHO, that should be clear from the returning part

     map(items => {