我一直认真地坚持让这个工作两天了。我正在使用ngx-bootstrap的typeahead构建异步类型。从HTML模板开始,在typeahead和所选对象的反应形式中有一个输入:
<input class="form-control"
formControlName="prefix"
typeaheadOptionField="name"
[typeahead]="accounts"
(typeaheadOnSelect)="onSelect($event)">
这里是我创建一个可观察的组件的组件,它首先调用我的http服务accountTypeAhead()
。然后,对于某些错误处理内容,http服务的响应将通过处理程序responseHandler()
发送,然后将有效负载返回给组件。
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, FormControl } from '@angular/forms';
import { ApiHandlerService } from 'app/services/api-handler/api-handler.service';
import { EmitIdService } from 'app/services/emit-id/emit-id.service';
import { UsersService } from '../../services/users.service';
import { TypeaheadMatch } from 'ngx-bootstrap/typeahead/typeahead-match.class';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
@Component({
selector: 'app-firm-modal',
templateUrl: './firm-modal.component.html'
})
export class FirmModalComponent implements OnInit {
accounts: Observable<any>;
selectedOption: any;
constructor(
private apiHandler: ApiHandlerService,
private idService: EmitIdService,
private fb: FormBuilder,
private users: UsersService
) {}
ngOnInit() {
this.accounts = Observable.create((observer: any) => {
observer.next(this.userForm.value.prefix);
}).mergeMap((prefix) => this.getAccounts(prefix));
this.userForm = this.fb.group({
prefix: new FormControl(),
accountsToAdd: new FormArray([]),
accountsToDelete: new FormArray([]),
email: new FormControl(),
name: new FormControl(),
rolesToAdd: new FormArray([]),
rolesToDelete: new FormArray([]),
userId: new FormControl(),
});
}
getAccounts(prefix) {
this.users.accountTypeAhead(prefix).subscribe(
response => {
this.apiHandler.responseHandler(response);
},
(err) => {
this.apiHandler.errorHandler(err);
}
);
}
}
来自服务器的有效负载格式化为
[
{
'id': 12,
'name': 'Rest test'
},
{
'id': 13,
'name': 'Rest test'
}
]
所以现在运行它,当我输入输入中的第一个字母时,我在控制台中收到此错误:
core.js:1448 ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
at subscribeToResult (subscribeToResult.js:74)
at MergeMapSubscriber._innerSub (mergeMap.js:138)
at MergeMapSubscriber._tryNext (mergeMap.js:135)
at MergeMapSubscriber._next (mergeMap.js:118)
at MergeMapSubscriber.Subscriber.next (Subscriber.js:92)
at Observable.eval [as _subscribe] (firm-modal.component.ts:135)
at Observable._trySubscribe (Observable.js:172)
at Observable.subscribe (Observable.js:160)
at MergeMapOperator.call (mergeMap.js:92)
at Observable.subscribe (Observable.js:157)
defaultErrorLogger @ core.js:1448
ErrorHandler.handleError @ core.js:1509
next @ core.js:5497
schedulerFn @ core.js:4331
SafeSubscriber.__tryOrUnsub @ Subscriber.js:240
SafeSubscriber.next @ Subscriber.js:187
Subscriber._next @ Subscriber.js:128
Subscriber.next @ Subscriber.js:92
Subject.next @ Subject.js:56
EventEmitter.emit @ core.js:4311
(anonymous) @ core.js:4771
ZoneDelegate.invoke @ zone.js:388
Zone.run @ zone.js:138
NgZone.runOutsideAngular @ core.js:4697
onHandleError @ core.js:4771
ZoneDelegate.handleError @ zone.js:392
Zone.runTask @ zone.js:191
ZoneTask.invokeTask @ zone.js:496
ZoneTask.invoke @ zone.js:485
timer @ zone.js:2025
setInterval (async)
scheduleTask @ zone.js:2046
ZoneDelegate.scheduleTask @ zone.js:407
onScheduleTask @ zone.js:297
ZoneDelegate.scheduleTask @ zone.js:401
Zone.scheduleTask @ zone.js:232
Zone.scheduleMacroTask @ zone.js:255
scheduleMacroTaskWithCurrentZone @ zone.js:1092
(anonymous) @ zone.js:2061
proto.(anonymous function) @ zone.js:1372
AsyncAction.requestAsyncId @ AsyncAction.js:71
AsyncAction.schedule @ AsyncAction.js:64
Scheduler.schedule @ Scheduler.js:46
DebounceTimeSubscriber._next @ debounceTime.js:92
Subscriber.next @ Subscriber.js:92
schedulerFn @ core.js:4331
SafeSubscriber.__tryOrUnsub @ Subscriber.js:240
SafeSubscriber.next @ Subscriber.js:187
Subscriber._next @ Subscriber.js:128
Subscriber.next @ Subscriber.js:92
Subject.next @ Subject.js:56
EventEmitter.emit @ core.js:4311
TypeaheadDirective.onInput @ typeahead.directive.js:105
(anonymous) @ FirmModalComponent.html:66
handleEvent @ core.js:13547
callWithDebugContext @ core.js:15056
debugHandleEvent @ core.js:14643
dispatchEvent @ core.js:9962
(anonymous) @ core.js:10587
(anonymous) @ platform-browser.js:2628
ZoneDelegate.invokeTask @ zone.js:421
onInvokeTask @ core.js:4740
ZoneDelegate.invokeTask @ zone.js:420
Zone.runTask @ zone.js:188
ZoneTask.invokeTask @ zone.js:496
invokeTask @ zone.js:1517
globalZoneAwareCallback @ zone.js:1543
我刚开始学习使用observables,所以我不知道该怎么做。
新堆栈跟踪:
core.js:1448 ERROR TypeError: Cannot read property 'slice' of undefined
at TypeaheadDirective.prepareMatches (typeahead.directive.js:316)
at TypeaheadDirective.finalizeAsyncCall (typeahead.directive.js:291)
at SafeSubscriber.eval [as _next] (typeahead.directive.js:237)
at SafeSubscriber.__tryOrUnsub (Subscriber.js:240)
at SafeSubscriber.next (Subscriber.js:187)
at Subscriber._next (Subscriber.js:128)
at Subscriber.next (Subscriber.js:92)
at MergeMapSubscriber.notifyNext (mergeMap.js:151)
at InnerSubscriber._next (InnerSubscriber.js:25)
at InnerSubscriber.Subscriber.next (Subscriber.js:92)
defaultErrorLogger @ core.js:1448
ErrorHandler.handleError @ core.js:1509
next @ core.js:5497
schedulerFn @ core.js:4331
SafeSubscriber.__tryOrUnsub @ Subscriber.js:240
SafeSubscriber.next @ Subscriber.js:187
Subscriber._next @ Subscriber.js:128
Subscriber.next @ Subscriber.js:92
Subject.next @ Subject.js:56
EventEmitter.emit @ core.js:4311
(anonymous) @ core.js:4771
ZoneDelegate.invoke @ zone.js:388
Zone.run @ zone.js:138
NgZone.runOutsideAngular @ core.js:4697
onHandleError @ core.js:4771
ZoneDelegate.handleError @ zone.js:392
Zone.runTask @ zone.js:191
ZoneTask.invokeTask @ zone.js:496
ZoneTask.invoke @ zone.js:485
timer @ zone.js:2025
setInterval (async)
scheduleTask @ zone.js:2046
ZoneDelegate.scheduleTask @ zone.js:407
onScheduleTask @ zone.js:297
ZoneDelegate.scheduleTask @ zone.js:401
Zone.scheduleTask @ zone.js:232
Zone.scheduleMacroTask @ zone.js:255
scheduleMacroTaskWithCurrentZone @ zone.js:1092
(anonymous) @ zone.js:2061
proto.(anonymous function) @ zone.js:1372
AsyncAction.requestAsyncId @ AsyncAction.js:71
AsyncAction.schedule @ AsyncAction.js:64
Scheduler.schedule @ Scheduler.js:46
DebounceTimeSubscriber._next @ debounceTime.js:92
Subscriber.next @ Subscriber.js:92
schedulerFn @ core.js:4331
SafeSubscriber.__tryOrUnsub @ Subscriber.js:240
SafeSubscriber.next @ Subscriber.js:187
Subscriber._next @ Subscriber.js:128
Subscriber.next @ Subscriber.js:92
Subject.next @ Subject.js:56
EventEmitter.emit @ core.js:4311
TypeaheadDirective.onInput @ typeahead.directive.js:105
(anonymous) @ FirmModalComponent.html:66
handleEvent @ core.js:13547
callWithDebugContext @ core.js:15056
debugHandleEvent @ core.js:14643
dispatchEvent @ core.js:9962
(anonymous) @ core.js:10587
(anonymous) @ platform-browser.js:2628
ZoneDelegate.invokeTask @ zone.js:421
onInvokeTask @ core.js:4740
ZoneDelegate.invokeTask @ zone.js:420
Zone.runTask @ zone.js:188
ZoneTask.invokeTask @ zone.js:496
invokeTask @ zone.js:1517
globalZoneAwareCallback @ zone.js:1543
答案 0 :(得分:0)
mergeMap
接受更高阶的可观察量(Observable
Observable
)并变为普通的可观察量。
您要求mergeMap((prefix) => this.getAccounts(prefix))
getAccounts
返回可观察的可观察量,但
getAccounts(prefix) {
this.users.accountTypeAhead(prefix).subscribe(
response => {
this.apiHandler.responseHandler(response);
},
(err) => {
this.apiHandler.errorHandler(err);
}
);
}
只是getAccounts(prefix): void
- 什么都不返回,Observable不能为mergeMap处理它。您应该返回正确的observable以期望mergeMap行为。