Angular 根据RxJS HTTP请求中的用户输入检查对象数组中的对象是否存在
通过RxJS使用数据/动作流,如果用户输入了无效的间隔号,我想返回/传递一个错误。如果与用户输入的编号匹配,我的代码当前将返回一个间隔对象,但是如果用户输入的间隔列表中不存在的无效间隔编号,我不知道如何抛出错误Angular 根据RxJS HTTP请求中的用户输入检查对象数组中的对象是否存在,angular,rxjs,rxjs6,rxjs-observables,rxjs-pipeable-operators,Angular,Rxjs,Rxjs6,Rxjs Observables,Rxjs Pipeable Operators,通过RxJS使用数据/动作流,如果用户输入了无效的间隔号,我想返回/传递一个错误。如果与用户输入的编号匹配,我的代码当前将返回一个间隔对象,但是如果用户输入的间隔列表中不存在的无效间隔编号,我不知道如何抛出错误 为了在多个组件/页面之间共享数据,我在BayService类中完成了大部分工作: ,但如何处理无效数字?例如,当用户在键入数字后按下submit按钮时,如何根据我的observable检查它是否无效,然后将某些内容返回到我的组件以显示在UI上?目前,我在客户端检查用户键入的内容,然后显示
这是我的Bay.page.ts:我认为最简单的解决方案是为您的响应创建一个包装器
导出接口BaySelectionResponse{
类型:BayResponseType;
消息:字符串;
海湾:海湾;;
}
导出枚举BayResponseType{
ERR=“间隔错误”,
OK=“成功”,
NOT_IN_LIST=“列表中找不到间隔”
}
通过这种方式,您可以适当地分离责任
您的服务将根据响应分配状态和消息,您的页面可以决定如何实现显示结果
使用这种方法,您甚至可以根据服务返回的状态,使用适当的模板将结果显示分离到自己的组件中
例子
服务
首先,让我们创建一个服务,该服务的作用是检查远程设备的可用数据:
@Injectable({providedIn:'root'})
导出类ApiLookupService{
}
首先,我们需要一个方法,该方法将简单地查询我们的远程所有可能的值。我已经用rxjsof
函数模拟了这一点
mockNumbersEndpoint(){
返回([1,3,7,9,13])
}
其次,我们需要一种方法,它将接受来自消费者(即我们的路由组件,它将利用我们的服务)的输入,该方法可以根据给定的输入值检查响应
checkValidity(输入:数字):可观察{
//通过管道将来自api的响应转换为ValidityResponseModel
返回此.mockNumbersEndpoint().pipe(
开关映射(apiResponse=>{
const validity={}作为ValidityResponseModel;
//检查用户的输入是否有效:是否存在于服务器的响应中
if(apiResponse.some(number=>input==number)){
返回(this.createValidityResponse)(
`您选择的值${input}可用`,
ValidityResponseTypes.SUCCESS,
输入
));
}
//如果我们的代码达到这一点,这意味着我们没有找到用户输入
返回(this.createValidityResponse)(
`您选择的值${input}不可用`,
ValidityResponseTypes.INVALID,
输入
));
}),
//我们现在已经离开了“开关”的高度,回到管道中。
//如果抛出任何错误(如网络问题),我们将包括catchError来处理。
catchError(错误=>{
返回(this.createValidityResponse)(
“您的请求出现问题”,
ValidityResponseType.ERR,
输入
));
})
)
}
最后,我添加了一个实用函数,它将响应重组为ValidityResponseType
createValidityResponse(消息:string,responseType:ValidityResponseType,响应:number):ValidityResponseModel{
返回{
消息
响应类型,
响应
}作为ValidityResponseModel
}
全套服务清单
@Injectable({providedIn:'root'})
导出类ApiLookupService{
mockNumbersEndpoint(){
返回([1,3,7,9,13])
}
检查有效性(输入:数字):可观察{
返回此.mockNumbersEndpoint().pipe(
开关映射(apiResponse=>{
const validity={}作为ValidityResponseModel;
if(apiResponse.some(number=>input==number)){
返回(this.createValidityResponse)(
`您选择的值${input}可用`,
ValidityResponseTypes.SUCCESS,
输入
));
}
返回(this.createValidityResponse)(
`您选择的值${input}不可用`,
ValidityResponseTypes.INVALID,
输入
));
}),
catchError(错误=>{
返回(this.createValidityResponse)(
“您的请求出现问题”,
ValidityResponseType.ERR,
输入
));
})
)
}
createValidityResponse(消息:string,responseType:ValidityResponseType,响应:number):ValidityResponseModel{
返回{
消息
响应类型,
响应
}作为ValidityResponseModel
}
}
使用服务的组件
因为在最初的问题中,当用户点击enter时,您执行检查,所以我选择实现一个表单
组件
@组件({
templateUrl:'./demo.component.html',
样式URL:['./demo.component.scss']
})
导出类DemoComponent实现OnInit{
组:FormGroup;
responseType=ValidityResponseType;
validityResponse!:ValidityResponseModel;
构造函数(私有fb:FormBuilder,私有服务:ApiLookupService){
this.group=fb.group({
输入:fb.control(0,[Validators.minLength(1)])
})
}
ngOnInit():void{
}
//提交。
对于
private baysUrl = 'api/bays';
bays$ = this.http.get<Bay[]>(this.baysUrl)
.pipe(
tap(data => console.log('Bays: ', JSON.stringify(data))),
catchError(this.handleError)
);
/*--------------------------------------------------------------*/
// Grab A Single Bay
private baySelectedSubject = new BehaviorSubject<number>(0);
baySelectedAction$ = this.baySelectedSubject.asObservable();
selectedBay$ = combineLatest([
this.bays$,
this.baySelectedAction$
])
.pipe(
map(([bays, selectedBayNumber]) =>
bays.find(bay => bay.bayCode === selectedBayNumber)
),
);
selectedBayChanged(selectedBayNumber: number): void {
this.baySelectedSubject.next(selectedBayNumber);
}
onSubmit() {
this.bayDoesNotExistError = false;
this.bayService.selectedBayChanged(this.bayForm.get('bayStart').value);
this.navCtrl.navigateForward([`/results/`]);
this.bayForm.reset();
}