Home > Blockchain >  Angular: Filter Observable<SomeObject[ ]> provided with a substring as a parameter
Angular: Filter Observable<SomeObject[ ]> provided with a substring as a parameter

Time:12-18

The situation:

I have a class with two properties, id and tagName. I have a json file with an array that matches said class. I want to extract all the items in the array that their tagName contains a given substring as a parameter, not equal to tagName but anywhere within the string. I am trying this in a service, in a function that returns an observable of type said class above. In the following attempts below I will be using "java" as the search parameter.

The class:

export class TechTag {
    id?: number;
    tagName!: string;
}

The function inside de service that returns every object:

getAllTechTags(): Observable<TechTag[]> {
    return this.http.get<TechTag[]>(this.baseUrl);
}

Url of JSON file:

"../assets/techTags.json"

Sample of the file:

[
  {
    "id": 1,
    "tagName": ".net"
  },
  {
    "id": 2,
    "tagName": "html"
  },
  {
    "id": 3,
    "tagName": "javascript"
  },
  {
    "id": 4,
    "tagName": "css"
  },
  {
    "id": 5,
    "tagName": "php"
  },
  {
    "id": 8,
    "tagName": "c"
  },
  {
    "id": 9,
    "tagName": "c#"
  },
  {
    "id": 10,
    "tagName": "c  "
  },

How I check the results in the component:

  ngOnInit(): void {

    let techTags: TechTag[];

    this.techTagsService.searchTechTags("java").subscribe(
      {
        next: (response => {
          techTags = response;
        }),
        complete: () => {
          console.log(techTags);
        }
      }
    );

  }

My attempts:

Attempt #1

  searchTechTags(tagName: string): Observable<TechTag[]> {
    return this.http.get<TechTag[]>(this.baseUrl).pipe(map(data => data.filter(tags => 
    tags.tagName == tagName)));
  }

Result #1 (only returns java)

[
    {
        "id": 17,
        "tagName": "java"
    }
]

Attempt #2

  searchTechTags(tagName: string): Observable<TechTag[]> {
    return this.http.get<TechTag[]>(this.baseUrl).pipe(map(data => data.filter(tags => 
    tagName.includes(tags.tagName))));
  }

Result #2 (doesn't return javascript)

[
    {
        "id": 17,
        "tagName": "java"
    },
    {
        "id": 11644,
        "tagName": "j"
    },
    {
        "id": 118435,
        "tagName": "ava"
    }
]

Attempt #3

  searchTechTags(tagName: string): Observable<TechTag[]> {
    return this.http.get<TechTag[]>(this.baseUrl).pipe(map(data => data.filter(tags => 
    tags.tagName.includes(tagName))));
  }

Result #3 (doesn't even work)

ERROR TypeError: tags.tagName.includes is not a function

Attempt #4

  searchTechTags(tagName: string): Observable<TechTag[]> {
    return this.http
      .get<TechTag[]>(this.baseUrl)
      .pipe(
        map((data) => data.filter(p => p.tagName.indexOf(tagName) !== -1))
      )
  }

Result #4

ERROR TypeError: p.tagName.indexOf is not a function

CodePudding user response:

Add toString() to tagName before filtering it, because it looks like an object not a string.

map((data) => data.filter(p => p.tagName.toString().indexOf(tagName) !== -1))
  • Related