Angular 4 合并来自多个 HTTP 请求的数据
Angular 4 combine data from multiple HTTP requests
我正在使用 angular 4,我尝试从 2 个端点获取数据,但我无法理解 rxjs。
使用此代码我只能获取学生和用户的列表。
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" }]
我想首先获取所有学生,然后比较 UserID,如果它与用户相同,然后我将两个对象合并为一个,直到得到这样的数组:
{"ID" : 1 , "SchoolCode": "A150","Name": "Rick" , "FamilyName" , "Grimes" }
我想我应该使用平面图,但我确实尝试编写代码,但它对我不起作用,而且我没有找到具有这种逻辑的示例。
你能帮帮我吗
您可以尝试以下方法:
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$;
}
您可以在以下代码中使用 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
我正在使用 angular 4,我尝试从 2 个端点获取数据,但我无法理解 rxjs。
使用此代码我只能获取学生和用户的列表。
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" }]
我想首先获取所有学生,然后比较 UserID,如果它与用户相同,然后我将两个对象合并为一个,直到得到这样的数组:
{"ID" : 1 , "SchoolCode": "A150","Name": "Rick" , "FamilyName" , "Grimes" }
我想我应该使用平面图,但我确实尝试编写代码,但它对我不起作用,而且我没有找到具有这种逻辑的示例。
你能帮帮我吗
您可以尝试以下方法:
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$;
}
您可以在以下代码中使用 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