RxJS - 条件连接并合并来自响应的对象
RxJS - Conditional Concat and merge objects from response
我目前正在开发一个 ionic 5 应用程序,我有 2 个可观察对象,它们 return 有 2 个不同对象类型的数组。
我想将对象的一些属性混合在一个新类型的对象中,但我只想在第一个 returns 值时对服务器进行第二次调用。
示例:
obs1$: Observable<{id: string, name: string, active: boolean}[]>;
obs2$: Observable<{id: string, location: Location, year: date}[]>;
newObs$: Observable<{id: string, name: string, year: date}[]>;
我要:
- 致电
obs1$
- 如果
obs1$
returns 值则调用 obs2$
,否则 returns []
- 当
obs2$
returns 值时,return 对象数组映射两个可观察对象的结果
我猜你在 class。你可以这样做。但是请确保在映射之前初始化您的可观察对象。
obs1$: Observable<{ id: string; name: string; active: boolean }[]>;
obs2$: Observable<{ id: string; location: Location; year: Date }[]>;
newObs$ = this.obs1$.pipe(
switchMap((item) => {
const emptyArray: { id: string; name: string; year: Date }[] = [];
return item? this.obs2$.pipe(
map((item2) => {
const others = item2.map((ent2) => {
const index = item.findIndex(ent1 => ent1.id === ent2.id)
let name = ''
if(index !== -1){
name = item[index].name
}
const id = ent2.id;
const year = ent2.year;
return {name, id, year}
});
return others
}),
)
: of(emptyArray);
}),
);
我添加了一些接口以使代码更易于阅读。我在这里假设您的第一个可观察 returns 没有值时是一个空数组。如果它 returns null
而不是,您可能想要删除 switchMap
.
中的 .length
下面的代码工作得很好。
interface First {
id: string;
name: string;
active: boolean;
}
interface Second {
id: string;
location: Location;
year: Date;
}
interface Result {
id: string;
name: string;
year: Date;
}
...
const first$: Observable<First[]>; // Make sure it's initialized
const second$: Observable<Second[]>; // Make sure it's initialized
...
const result$: Observable<Result[]> = first$.pipe(
switchMap(firstArray => !firstArray.length
? of([])
: second$.pipe(
map(secondArray => firstArray
.filter(a => secondArray.some(b => a.id === b.id))
.map(a => ({ first: a, second: secondArray.find(b => a.id === b.id) }))
.map(values => ({...values.first, year: values.second.year }))
)
)
)
);
我目前正在开发一个 ionic 5 应用程序,我有 2 个可观察对象,它们 return 有 2 个不同对象类型的数组。 我想将对象的一些属性混合在一个新类型的对象中,但我只想在第一个 returns 值时对服务器进行第二次调用。
示例:
obs1$: Observable<{id: string, name: string, active: boolean}[]>;
obs2$: Observable<{id: string, location: Location, year: date}[]>;
newObs$: Observable<{id: string, name: string, year: date}[]>;
我要:
- 致电
obs1$
- 如果
obs1$
returns 值则调用obs2$
,否则 returns[]
- 当
obs2$
returns 值时,return 对象数组映射两个可观察对象的结果
我猜你在 class。你可以这样做。但是请确保在映射之前初始化您的可观察对象。
obs1$: Observable<{ id: string; name: string; active: boolean }[]>;
obs2$: Observable<{ id: string; location: Location; year: Date }[]>;
newObs$ = this.obs1$.pipe(
switchMap((item) => {
const emptyArray: { id: string; name: string; year: Date }[] = [];
return item? this.obs2$.pipe(
map((item2) => {
const others = item2.map((ent2) => {
const index = item.findIndex(ent1 => ent1.id === ent2.id)
let name = ''
if(index !== -1){
name = item[index].name
}
const id = ent2.id;
const year = ent2.year;
return {name, id, year}
});
return others
}),
)
: of(emptyArray);
}),
);
我添加了一些接口以使代码更易于阅读。我在这里假设您的第一个可观察 returns 没有值时是一个空数组。如果它 returns null
而不是,您可能想要删除 switchMap
.
.length
下面的代码工作得很好。
interface First {
id: string;
name: string;
active: boolean;
}
interface Second {
id: string;
location: Location;
year: Date;
}
interface Result {
id: string;
name: string;
year: Date;
}
...
const first$: Observable<First[]>; // Make sure it's initialized
const second$: Observable<Second[]>; // Make sure it's initialized
...
const result$: Observable<Result[]> = first$.pipe(
switchMap(firstArray => !firstArray.length
? of([])
: second$.pipe(
map(secondArray => firstArray
.filter(a => secondArray.some(b => a.id === b.id))
.map(a => ({ first: a, second: secondArray.find(b => a.id === b.id) }))
.map(values => ({...values.first, year: values.second.year }))
)
)
)
);