gpt4 book ai didi

angular - switchMap 类型 void 不可分配给类型 ObservableInput<{}>

转载 作者:太空狗 更新时间:2023-10-29 18:00:28 24 4
gpt4 key购买 nike

我使用 Angular http 和 RXJS 来检索一些应用程序设置。 http 使用 RXJS shareReplay 来避免多次相同的调用。

这按预期工作,检查“网络”选项卡时我只能看到对我的后端 API 的 1 次调用。

我的应用程序中的某些组件将调用服务并使用结果来呈现页面。其他组件,需要像上面那样调用服务,然后再次对结果做“某事”,例如更多的 http 调用,然后呈现页面。当尝试稍后执行时,出现类型错误:

Argument of type '(result: any) => void' is not assignable to parameter of type '(value: any, index: number)' => ObservableInput<{}>

关于我的 switchMap 使用。

-- 没有 switchMap 的工作简单示例 ----

购物车.component.ts

ngOnInit() {
this.systemPreferences.getPreferences()
.subscribe(
(result: any) => {
this.headerTitle = result.title || '';
},
(err) => {
console.log('there has been an error');
},
() => // Some completion code
);
}

systemPreferences.service.ts:

const CACHE_SIZE = 1;

export class SystemPreferences {
private $cache: Observable<Object>

private requestConfig() {
return this.http.get("/api/some/endpoint").pipe(
map(response => response.value)
);
}

public getPreferences() {
if (!this.cache$) {
this.cache$ = this.requestConfig().pipe(
shareReplay(CACHE_SIZE)
);
}

return this.cache$;
}
}

/api/some/endpoint 示例响应:

{
"appName": "Tables Forks and Spoons",
"title": "My title",
"regionUrls": [
"http://www.region1.com:8021",
"http://www.region2.com:8021",
"http://www.region3.com:8021",
"http://www.region4.com:8021"
],
"nonRegionUrls": [
"http://www.non-region1.com:8021",
"http://www.non-region2.com:8021",
"http://www.non-region3.com:8021",
"http://www.non-region4.com:8021"
]
}

-- 使用 switchMap 的类型错误简单示例 ----

购物车.component.ts

ngOnInit() {
this.systemPreferences.getPreferences()
.pipe(
.switchMap((result: any) => {

this.systemPreferences.getLiveUrl(result['regionUrls']);

}))
.subscribe(
(result: any) => {
this.liveLink = result.liveLink; // result.livelink is added as part of this.systemPreferences.getLiveUrl above
this.headerTitle = result.title || '';
},
(err) => {
console.log('there has been an error');
}
);
}

systemPreferences.service.ts:

const CACHE_SIZE = 1;

export class SystemPreferences {
private $cache: Observable<Object>

private requestConfig() {
return this.http.get("/api/some/endpoint").pipe(
map(response => response.value)
);
}

public getPreferences() {
if (!this.cache$) {
this.cache$ = this.requestConfig().pipe(
shareReplay(CACHE_SIZE)
);
}

return this.cache$;
}

public getLiveUrl(urls: any) {
let promises = [];

urls.forEach((url) => {
promises.push(this.http.get(url + 'some/endpoint/'));
});

const results = forkJoin(promises) {
.subscribe((data: any) => {
return this.getBest(data);
}
}
}

public getBest(data: any) {
// Loops through data, and returns a single URL as a string
// 'http//www.thebesturltouse.com'
}
}

更新:

尝试按照建议返回第二个 observable,见下文,具有与上述相同的类型 void 错误。

购物车.component.ts

ngOnInit() {
this.systemPreferences.getPreferences()
.pipe(
.switchMap((result: any) => {
return this.systemPreferences.getLiveUrl(result['regionUrls']);
}))
.subscribe(
(result: any) => {
this.liveLink = result.liveLink; // result.livelink is added as part of this.systemPreferences.getLiveUrl above
this.headerTitle = result.title || '';
},
(err) => {
console.log('there has been an error');
}
);
}

systemPreferences.service.ts:

const CACHE_SIZE = 1;

export class SystemPreferences {
private $cache: Observable<Object>
private $switchObs: Observable<Object>

private requestConfig() {
return this.http.get("/api/some/endpoint").pipe(
map(response => response.value)
);
}

public getPreferences() {
if (!this.cache$) {
this.cache$ = this.requestConfig().pipe(
shareReplay(CACHE_SIZE)
);
}

return this.cache$;
}

public getLiveUrl(urls: any) {
let promises = [];

urls.forEach((url) => {
promises.push(this.http.get(url + 'some/endpoint/'));
});

const results = forkJoin(promises) {
.subscribe((data: any) => {
this.$switchObs = this.getBest(data);
return this.$switchObs;
}
}
}

public getBest(data: any) {
// Loops through data, and returns a single URL as a string
// 'http//www.thebesturltouse.com'
}
}

更新到多个 switchMap

购物车.component.ts

ngOnInit() {
this.systemPreferences.getPreferences()
.pipe(
.switchMap((result: any) => {
return this.systemPreferences.getLiveUrl(result['regionUrls']);
}),
.switchMap((liveRegion: any) => {
return this.systemPreferences.getBest(liveRegion);
}))
.subscribe(
(bestUrl: String) => {
console.log('best');
console.log(bestUrl);
},
(err) => {
console.log('there has been an error');
}
);
}

systemPreferences.service.ts:

const CACHE_SIZE = 1;

export class SystemPreferences {
private $cache: Observable<Object>
private $switchObs: Observable<String>

private requestConfig() {
return this.http.get("/api/some/endpoint").pipe(
map(response => response.value)
);
}

public getPreferences() {
if (!this.cache$) {
this.cache$ = this.requestConfig().pipe(
shareReplay(CACHE_SIZE)
);
}

return this.cache$;
}

public getLiveUrl(urls: any) {
let promises = [];

urls.forEach((url) => {
promises.push(this.http.get(url + 'some/endpoint/'));
});

return forkJoin(promises);
}

public getBest(data: any) {
// Loops through data, and returns a single URL as a string
//
return this.$switchObs; // = 'http//www.thebesturltouse.com'
}
}

通过上面的内容,在 console.log('best')/console.log(bestUrl) 上,我看到:

'best'
h
'best'
t
'best'
t
'best'
p
'best'
:
'best'
/
'best'
/
'best'
w
'best'
w
'best'
w
'best'
.
'best'
b
etc etc etc

而不只是字符串 http//www.thebesturltouse.com


更新。

在多 switchMap 示例中,如果我返回 Obserbable.of(this.$switchObs);我得到预期的单字符串 URL。

感觉这不是解决此问题的最佳方法。

最佳答案

问题与 switchMap 运算符本身无关。事实上,您的 getLiveUrl 方法属于 void 类型。 switchMap 需要一个返回可观察值作为输入参数的函数。所以您希望 getLiveUrl 返回一个可观察对象。为此,代码可能如下所示(请注意,我不是 100% 确定 getBest 实际在做什么,这可能会影响解决方案。):

 public getLiveUrl(urls: any) {
let promises = [];

urls.forEach((url) => {
promises.push(this.http.get(url + 'some/endpoint/'));
});

return forkJoin(promises).pipe(
map(data => this.getBest(data))
);
}

我仍然不是 100% 确定您实际想要实现的目标,但我希望这对您有所帮助。

关于angular - switchMap 类型 void 不可分配给类型 ObservableInput<{}>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53628962/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com