我正在尝试将 API 调用的响应映射到 Product 对象。我似乎找不到正确的方法。
响应的结构如下:
{
"data": [
{
"id": 1,
"name": "keyboard",
"details": {
"parent": 1,
"price": 50,
"other": "info"
}
},
{
"id": 2,
"name": "mouse",
"details": {
"parent": 2,
"other": "info",
"price": 20
}
}
],
"total-records": 2,
"more": "something"
}
Run Code Online (Sandbox Code Playgroud)
无法保证回复详细信息的顺序。(详细说明价格)。我试图将上面的对象映射到一个仅包含以下属性的新对象:
{
"id": 1,
"name": "keyboard",
"price": 50
},
{
"id": 2,
"name": "mouse",
"price": 20
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 Angular 和 Observables 来获取数据。现在我正在获取值,对其进行映射,并且可以仅获取详细信息或第一级对象属性,例如data.id或data.name。然而,获取价格等详细信息对我来说有点令人困惑。
我研究了很多关于 mergemap、flatmap、甚至 lodash 的知识,并花了无数个小时试图弄清楚,但我似乎找不到正确的方法。
我可以在地图组合中使用过滤器来实现此目的吗?任何信息都受到高度赞赏。
到目前为止,这是我的代码:
{
"data": [ …Run Code Online (Sandbox Code Playgroud)这是我的package.json文件:
"dependencies": {
"@angular/animations": "~7.1.0",
"@angular/common": "~7.1.0",
"@angular/compiler": "~7.1.0",
"@angular/core": "~7.1.0",
"@angular/forms": "~7.1.0",
"@angular/material": "^7.1.1",
"@angular/platform-browser": "~7.1.0",
"@angular/platform-browser-dynamic": "~7.1.0",
"@angular/router": "~7.1.0",
"core-js": "^2.5.4",
"ng2-opd-popup": "^1.1.21",
"rxjs": "~6.3.3",
"tslib": "^1.9.0",
"zone.js": "~0.8.26"
Run Code Online (Sandbox Code Playgroud)
service.ts文件代码如下:
import { Injectable } from '@angular/core';
import { Http, Headers} from '@angular/http';
import 'rxjs/add/operator/map';
//import { Observable } from 'rxjs/Observable';
//import 'rxjs/add/observable';
import { Observable} from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class EmpService {
employees=[];
constructor(private _http: Http) { }
addEmployee(info){
return this._http.post("http://localhost/data/insert.php",info)
.map(()=>""); …Run Code Online (Sandbox Code Playgroud) 尝试从服务器获取数据,每 10 秒间隔一次服务。如果价格返回,则停止区间。代码如下:
但我收到错误:
错误 TypeError:您在需要流的地方提供了“未定义”。您可以提供 Observable、Promise、Array 或 Iterable。
代码:
public Respond() {
this.dataService.WaitingForServiceRespond()
.pipe((
debounceTime(2000),
switchMap((r: any) => {
if (!r.price) {
setInterval(() => {
return this.Respond();
}, 10000)
} else {
this.dataService.user.payment = r;
console.log('price returned', r);
return ''
}
})
))
.subscribe(e => {
console.log(e)
})
Run Code Online (Sandbox Code Playgroud)
}
在 Angular 6+ httpClient 中,可以将请求配置为获取完整响应。
可观察到的响应可以通过管道传输到map和catchError运算符中。
执行何时通过map运算符以及何时执行catchError?
它取决于响应状态代码吗?
例如,如果response.status === 200然后转到map,否则转到catchError?
如果不仅状态 200 转到map,那么还有哪些?
会进入哪些状态catchError?
getData(): Observable<[]> {
return this.http.get(this.apiUrl, {observe: 'response'}).pipe(
map((response: HttpResponse<any>) => {
return response.status === 200;
}),
catchError((errorResponse: HttpErrorResponse) =>
// which value may be logged here?
console.log(errorResponse.status);
of(false);
));
}
Run Code Online (Sandbox Code Playgroud) 我想要一个可观察的对象,当取消订阅时,它会调用一个函数,但只有当它取消订阅而没有错误且没有完成时。我尝试构建的可观察对象通常会与另一个可观察对象竞争。我希望当另一个可观察的“获胜”时,这个可观察的执行一个函数。
我尝试了 Finalize 运算符,但它总是执行。
播放.ts
import { timer } from "rxjs";
import { takeUntil, finalize } from "rxjs/operators";
import errorobs$ from "./errorobs";
export default function() {
return timer(10000).pipe(
takeUntil(errorobs$),
finalize(finalFunc)
);
}
function finalFunc() {
console.log("final function executed");
}
Run Code Online (Sandbox Code Playgroud)
错误对象.ts
import { fromEvent } from "rxjs";
import { map } from "rxjs/operators";
export default fromEvent(document.getElementById("errorBtn"), "click").pipe(
map(() => {
throw new Error("my error");
})
);
Run Code Online (Sandbox Code Playgroud)
我在这里做了一个小演示https://codesandbox.io/s/q7pwowm4l6
单击开始以启动“可观察的”。
单击“取消”以使其他可观察的获胜
点击error生成错误
这让我很头疼……以下代码确实按预期工作:
const s$ = new Subject<any>();
s$.pipe(
switchMap(
x => {
debugger;
return myService.getSth();
}
)
).subscribe(x => {
debugger;
});
s$.next();
Run Code Online (Sandbox Code Playgroud)
无论debugger在switchMap和subscribe部分被击中。
但是,如果我将其拆分(我想将整个管道内容移动到单独的库中),switchMap则不再调用 中的调试器,这意味着不会调用此特定示例中的服务:
const s$ = new Subject<any>();
s$.pipe(
switchMap(
x => {
debugger;
return myService.getSth();
}
)
);
// ...
s$.subscribe(x => {
debugger;
});
s$.next();
Run Code Online (Sandbox Code Playgroud)
我在这里想念什么?
为什么我们在下面的代码中使用两个过滤器而不是一个?
fromEvent<MouseEvent>(this.mapElement, "click")
.pipe(
filter(e => !this.props.disableEvents),
filter(_ => !this.mouseState.moved && mouseDownInMap)
)
.subscribe(e => {});
Run Code Online (Sandbox Code Playgroud)
为什么不:
fromEvent<MouseEvent>(this.mapElement, "click")
.pipe(filter( e => !this.props.disableEvents && !this.mouseState.moved && mouseDownInMap))
.subscribe(e => {});
Run Code Online (Sandbox Code Playgroud)
另外,.pipe()如果它也可以在没有管道的情况下工作,为什么我们需要?
我有多个在页面生命周期内发出值的可观察对象。例如:
chartData$: Observable;
tableData$: Observable;
filterData$: Observable;
Run Code Online (Sandbox Code Playgroud)
用户可以随时单击“下载”按钮,并获取结合了每个可观察量最后发出的值的 JSON:
downloadButtonClicked$.pipe(
combine chartData$, tableData$ and filterData$ // <- how do I get latest values here?
).subscribe(([chart, table, filter]) => downloadJson(chart, table, filter))
Run Code Online (Sandbox Code Playgroud)
但是,downloadJson当这 3 个可观察量中的任何一个在页面生命周期中发出值时,不应调用该函数,仅在单击“下载”时调用。
太长了;
工作最优雅的解决方案(如迈克建议) https://stackblitz.com/edit/typescript-jm3zma?file=index.ts
我一直在网上寻找解决方案,但找不到适合我的用户情况的任何解决方案。我正在使用MEAN堆栈(角度6),并且有注册表。我正在寻找一种对API执行多个HTTP调用的方法,每个方法都依赖于前一个方法返回的结果。我需要这样的东西:
firstPOSTCallToAPI('url', data).pipe(
result1 => secondPOSTCallToAPI('url', result1)
result2 => thirdPOSTCallToAPI('url', result2)
result3 => fourthPOSTCallToAPI('url', result3)
....
).subscribe(
success => { /* display success msg */ },
errorData => { /* display error msg */ }
);
Run Code Online (Sandbox Code Playgroud)
我需要使用哪种RxJS运算符组合来实现此目的?一种可能的解决方案是嵌套多个订阅,但是我想避免这种情况,并使用RxJS更好地实现。还需要考虑错误处理...
先谢谢了!