2017-09-01 4 views
6

角度4を使用していますが、2つのエンドポイントからデータを取得しようとしましたが、rxjsを理解する上で問題があります。角度4は複数のHTTPリクエストのデータを結合します

このコードでは、学生とユーザーのリストしか取得できません。

getStudent() { 
    return this.http.get(this.url + this.student_url, this.getHeaders()).map(res => res.json()); 
    } 

getUsers() { 
    return this.http.get(this.url + this.users_url, this.getHeaders()).map(res => res.json()); 
    } 

のは、これがデータであるとしましょう: 学生

[{"ID" : 1 , "SchoolCode": "A150", "UserID": 1 }, 
{"ID" : 5 , "SchoolCode": "A140" , "UserID": 3}, 
{"ID" : 9 , "SchoolCode": "C140" , "UserID": 4}] 

ユーザー

[{"ID" : 1 ,"Name": "Rick" , "FamilyName" , "Grimes" }, 
{"ID" : 4 ,"Name": "Carle" , "FamilyName" , "Grimes" }] 

私が最初にすべての学生が、それはユーザと同じだならば、私は両方の組み合わせユーザーIDを比較取得したいです私はこのような配列を得るまで、オブジェクトを1つにします:

{"ID" : 1 , "SchoolCode": "A150","Name": "Rick" , "FamilyName" , "Grimes" } 

私はフラットマップを使うべきだと思いますが、コードを書こうとしましたが、私にとってはうまく動作せず、そのようなロジックを持つ例は見つかりませんでした。

私を助けてください。

+0

flatmapをあなたはストリームを変更することができます。たとえば、学生に尋ねることができますし、特定の学生のためのコースのリストを得ることができます。 n;この場合は常に両方のリストが必要ですし、いくつかのロジックを実行できるので、forkjoin、マージ、または組み合わせが必要な場合があります – David

答えて

2

あなたは、次のコードでswitchMap演算子(flatMapの別名)を使用することができます。

// Observables mocking the data returned by http.get() 
const studentObs = Rx.Observable.from([ 
    {"ID" : 1 , "SchoolCode": "A150", "UserID": 1 }, 
    {"ID" : 5 , "SchoolCode": "A140" , "UserID": 4}, 
    {"ID" : 9 , "SchoolCode": "C140" , "UserID": 3} 
]); 
const userObs = Rx.Observable.from([ 
    {"ID" : 1, "Name": "Rick" , "FamilyName": "Grimes" }, 
    {"ID" : 3, "Name": "Tom" , "FamilyName": "Cruise" }, 
    {"ID" : 4, "Name": "Amy" , "FamilyName": "Poehler" } 
]); 
// Return an observable emitting only the given user. 
function getUser(userID) { 
    return userObs.filter(user => user.ID === userID); 
} 

studentObs 
    .switchMap(student => { 
    return getUser(student.UserID).map(user => { 
     // Merge the student and the user. 
     return Object.assign(student, {user: user}); 
    }) 
    }) 
    .subscribe(val => console.log(val)); 

このJSBinをチェックアウト:http://jsbin.com/batuzaq/edit?js,console

0

次の操作を試みることができる:

import { forkJoin } from 'rxjs/observable/forkJoin'; 

interface Student { 
    id: number; 
    schoolCode: string; 
    userId: number; 
} 

interface User { 
    id: number; 
    name: string; 
    familyName: string; 
} 

interface Merged { 
    id: number; 
    schoolCode: string; 
    name: string; 
    familyName: string; 
} 

getStudents(): Observable<Student[]> { 
    // Implementation 
    } 

    getUsers(): Observable<User[]> { 
    // Implementation 
    } 

    getMerged(): Observable<Merged[]> { 
    const student$ = this.getStudents(); 
    const users$ = this.getUsers(); 
    const merged$ = forkJoin(student$, users$) 
     .map(src => src[0].reduce((acc, current) => { 
     // acc is the accumulated result (list with mapped objects) 
     // current is an element of the students list 
     const user = src[1].find(u => u.id === current.userId); 
     // check if there is a user associated to the current student element 
     if (user) { // if there is a matching user, push new element to result list 
      acc.push({ 
      id: user.id, 
      name: user.name, 
      familyName: user.familyName, 
      schoolCode: current.schoolCode 
      }); 
     } 
     return acc; 
     // this could be changed to use a more immutable based approach 
     }, new Array<Merged>())); 
     // the seed value to start accumulating results is an empty list 
    return merged$; 
    } 
関連する問題