2017-09-01 14 views
6

Tôi đang sử dụng góc 4 và tôi cố gắng lấy dữ liệu từ 2 điểm cuối nhưng tôi gặp vấn đề khi hiểu rxj.Góc 4 kết hợp dữ liệu từ nhiều yêu cầu HTTP

bằng mã này tôi chỉ có thể nhận danh sách sinh viên và người dùng.

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()); 
    } 

Hãy nói rằng đây là dữ liệu: Student

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

tài

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

Tôi muốn nhận được đầu tiên tất cả học sinh sau đó so sánh UserID nếu nó giống như người dùng sau đó tôi kết hợp cả hai đối tượng thành một cho đến khi tôi nhận được một mảng như sau:

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

Tôi nghĩ rằng tôi nên sử dụng flatmap nhưng tôi đã cố gắng viết mã nhưng nó không làm việc cho tôi và tôi đã không tìm thấy một ví dụ với logic như vậy.

Bạn có thể giúp tôi không.

+0

flatMap cho phép bạn thay đổi luồng, ví dụ, bạn có thể yêu cầu học sinh và sau đó nhận danh sách các khóa học cho một sinh viên cụ thể sẽ là một optio tốt n; trong trường hợp này bạn luôn cần cả hai danh sách và sau đó bạn có thể làm một số logic, vì vậy bạn có thể cần forkjoin, hợp nhất hoặc kết hợp để làm như vậy – David

Trả lời

2

Bạn có thể sử dụng switchMap điều hành (bí danh của flatMap) trong đoạn mã sau:

// 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)); 

Check-out JSBin này: http://jsbin.com/batuzaq/edit?js,console

0

Bạn có thể thử như sau:

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$; 
    } 
Các vấn đề liên quan