您在预期的流中提供了“未定义”。您可以提供Observable,Promise,Array或Iterable

时间:2018-03-14 18:34:50

标签: angular rxjs ngx-bootstrap

我一直认真地坚持让这个工作两天了。我正在使用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

1 个答案:

答案 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行为。