אנגולר ו-Rxjs

נראה שימוש בפונקציות Rxjs עם הבאת מידע ממסד נתונים באנגולר.

נקודת הפתיחה היא תוכנית החיפוש בויקיפדיה שבנינו במאמר שימוש ב-Data ו-HTTP Requests.

בקובץ ה-service פנינו לפונקציה get שמחזירה observable.

קובץ wikipedia.service.ts

export class WikipediaService {
  wikiUrl = "https://en.wikipedia.org/w/api.php";

  constructor(private httpClient: HttpClient) { }

  search(term: string){
    let params = {
      action: "query",
      list: "search",
      origin: "*",
      format: "json",
      srsearch: term
    };

    return this.httpClient.get(this.wikiUrl, {params});
  }
}

כשהבקשה מסתיימת, ה-observable מחזיר ערך שמכיל את המידע שהוא הביא מה-API. אנחנו קוראים לפונקציה search מהקומפוננטה שלנו. כש-observable מטריג ערך, ה-observer שלנו יעבוד.

קובץ app.component.ts

export class AppComponent {
  pages = [];

  constructor(private wikipedia: WikipediaService){}

  onTerm(term: string){
    this.wikipedia.search(term).subscribe((result: any) =>{
      this.pages = result.query.search;
    });
  }
}

מכיוון שפונקציית get היא ללא הגדרה של סוג האובייקט שחוזר, היא גנרית, יכולות להיות שגיאות בקריאת האובייקט המוחזר.

משהו נוסף הוא שאנחנו מחזירים את כל ה-response עם פונקציית search כשמה שמעניין אותנו זה רק רשימת תוצאות החיפוש.

נגדיר interface שמתאר את תוצאות החיפוש שאנחנו רוצים על מנת להביא את המבנה שאנחנו מחפשים, נגיד לפונקציה get מה המבנה שאנחנו רוצים לקבל ועל ידי map נחזיר רק את החלק של ה-response שאנחנו צריכים.

קובץ wikipedia.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { map, Observable } from 'rxjs';

interface WikipediaResponse{
  query:{
    search:{
      title: string;
      snippet: string;
      pageid: number;
    }[]
  }
}

@Injectable({
  providedIn: 'root'
})
export class WikipediaService {
  wikiUrl = "https://en.wikipedia.org/w/api.php";

  constructor(private httpClient: HttpClient) { }

  search(term: string){
    let params = {
      action: "query",
      list: "search",
      origin: "*",
      format: "json",
      srsearch: term
    };

    return this.httpClient.get<WikipediaResponse>(this.wikiUrl, {params})
      .pipe(
        map(result => {
          return result.query.search;
        })
      )
  }
}

בקומפוננטה נקבל את ה-result ישירות.

קובץ app.component.ts

onTerm(term: string){
    this.wikipedia.search(term).subscribe(result =>{
      this.pages = result;
    });
}