אנגולר - למלא נתונים של אובזרבאבל במערך ולסנן את המערך הזה


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

this.http.get(url1).subscribe
(data1 => {
// code code code //
this.http.get(url2).subscribe
( data2 =>
{ /* code code code */ }/* end of 2nd request subscribe function*/
}// end of 1st request subscribe function

אז יצרתי קובץ service.ts, עם כל הקריאות מסוג get

//code
getData1(){/*code*/}
getData2(){/*code*/}
getData3(){/*code*/}
}

ובתוך detail.component.ts מילאתי את המערכים:

//code
ngOnInit() 
  {
    this.Service.getData1()
    .subscribe(/*fill array1 with data*/)

    this.Service.getData2()
    .subscribe(/*fill array2 with data*/)
  {

למרות שהמנוי הראשון עובד בסדר, השני לא - אבל אני לא מצליח להבין למה. אני בעצם מנסה למצוא את כל הפריטים שיש להם את המזהה המוגדר:

//code
public data2: any = []
public id = '123'
//code
ngOnInit() 
{
//code
this.Service.getData2()
    .subscribe
    (data2 =>
      {
        this.data2 = data2.filter(item => item.id === this.id)
        return data2
      }
    )
//code
}

האם יש איזו טעות בסינון אולי?

תשובה #1

למה אתה לא משתמש ב-forkJoin כאן?

שלב את כל הבקשות לאחת וקבל את כל התגובות יחד ואז סנן את הנתונים.

forkJoin הוא חלק מ-rxjs

import { forkJoin } from 'rxjs';  // RxJS 6 syntax

דוגמא:

שירות.ts

export class DataService {

  constructor(private http: HttpClient) { }

  public getAllForkJoin(): Observable<any[]> {
    let res1 = this.http.get(requestUrl1);
    let res2 = this.http.get(requestUrl2);
    let res3 = this.http.get(requestUrl3);
    return forkJoin([res1, res2, res3]);
  }
}

רכיב.ts

export class DemoComponent implements OnInit {
    public responseData1: any;
    public responseData2: any;
    public responseData3: any;

    constructor(private dataService: DataService) {}

    ngOnInit() {
        this.dataService.getAllForkJoin().subscribe(data => {
            this.responseData1 = data[0];
            this.responseData2 = data[1];
            this.responseData3 = data[1];
        });
    }
}

תשובה #2

אתה שואל את השאלה בצורה לא נכונה. או שרוצים ביצוע רציף או מקביל. ביצוע רציף הוא צפוי בזמן הקומפילציה, כלומר אתה יודע בוודאות באיזו סדר הקוד שלך יבוצע וכל מקטע הבא תלוי בהצלחת המקטע הקודם הישיר שלו לפחות. ביצוע מקביל שונה: ישנם סדרי ביצוע רבים אפשריים, חלקם נבחרים לפי החלטות ריצה שאינן צפויות.

אז: this.Service.get(url1).pipe(mergeMap(data1 => this.Service.get(url2)) יפיק ביצוע רציף למעט שאתה מאבד גישה ל-data1. למרות שזה נדרש בכמה הקשרים (די נדירים), אני מניח שהדבר שאתה באמת צריך הוא forkJoin(this.Service.get(url1), this.Service.get(url2)) שיניב - במקביל במקום ברצף - את שני התוצאות וכבר ברגע ששניהם מצליחים, ידחוף אותם למטה.

בנוסף, שים לב שאתה יכול לשרבט את שתי הגישות יחד: this.Service.get(url1).pipe(data1 => forkJoin(of(data1), this.Service.get(url2))) יבטיח שurl1 ייטען תחילה ואחריו url2, ועדיין ישמור את הנתונים משתי הכתובות. זה אפשרי, אבל ברוב המקרים חסר תועלת ואפילו מזיק.