首页 > 解决方案 > 使用 Angular 材料自动完成示例中的代码时出现 TypeError

问题描述

当我尝试使用角度材料自动完成来添加标签时,它在构造函数中崩溃并出现错误:

ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
    at Object.push../node_modules/rxjs/internal/util/subscribeTo.js.exports.subscribeTo (subscribeTo.js:42)
    at Object.subscribeToResult (subscribeToResult.js:7)
    at MergeMapSubscriber.push../node_modules/rxjs/internal/operators/mergeMap.js.MergeMapSubscriber._innerSub (mergeMap.js:132)
    at MergeMapSubscriber.push../node_modules/rxjs/internal/operators/mergeMap.js.MergeMapSubscriber._tryNext (mergeMap.js:129)
    at MergeMapSubscriber.push../node_modules/rxjs/internal/operators/mergeMap.js.MergeMapSubscriber._next (mergeMap.js:112)
    at MergeMapSubscriber.push../node_modules/rxjs/internal/Subscriber.js.Subscriber.next (Subscriber.js:103)
    at Observable._subscribe (subscribeToArray.js:9)
    at Observable.push../node_modules/rxjs/internal/Observable.js.Observable._trySubscribe (Observable.js:177)
    at Observable.push../node_modules/rxjs/internal/Observable.js.Observable.subscribe (Observable.js:162)
    at MergeMapOperator.push../node_modules/rxjs/internal/operators/mergeMap.js.MergeMapOperator.call (mergeMap.js:87)

我的代码灵感来自材料芯片自动完成示例https://stackblitz.com/angular/qdxrokeqakb?file=app%2Fchips-autocomplete-example.ts

组件片段:

export class CreateNewPersonalBookmarkComponent implements OnInit {
  ...
  allTags = [
    'java',
    'javascript',
    'nodejs'
  ];

  tagCtrl = new FormControl();

  filteredTags: Observable<any[]>;

  @ViewChild('tagInput') tagInput: ElementRef;

  constructor(
    private personalBookmarksStore: PersonalBookmarksStore,
    private formBuilder: FormBuilder,
    private keycloakService: KeycloakService,
    private bookmarkService: PublicBookmarksService,
    private markdownServce: MarkdownService,
    private publicBookmarkStore: BookmarkStore
  ) {

    this.filteredTags = this.tagCtrl.valueChanges.pipe(
      startWith(null),
      map((tag: string | null) => tag ? this.filter(tag) : this.allTags.slice())
    );
  }

  filter(name: string) {
    return this.allTags.filter(tag => tag.toLowerCase().indexOf(name.toLowerCase()) === 0);
  }

  selected(event: MatAutocompleteSelectedEvent): void {
    const tags = this.bookmarkForm.get('tags') as FormArray;
    tags.push(this.formBuilder.control(event.option.viewValue));
    this.tagInput.nativeElement.value = '';
    this.tagCtrl.setValue(null);
  }

  ...
}

和html模板:

<form [formGroup]="bookmarkForm" novalidate (ngSubmit)="saveBookmark(bookmarkForm.value)">
  .....
  <div id="tags">
    <mat-form-field  class="full-width">
      <mat-chip-list #chipList>
        <mat-chip *ngFor="let tag of tags.controls; let i = index;" [selectable]="selectable"
                  [removable]="removable" (removed)="remove(i)">
          {{tag.value}}
          <mat-icon matChipRemove *ngIf="removable">cancel</mat-icon>
        </mat-chip>
        <input placeholder="Tags* - max 5, use comma, space or enter to separate..."
               #tagInput
               [matChipInputFor]="chipList"
               [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
               [matChipInputAddOnBlur]="addOnBlur"
               [matAutocomplete]="auto"
               pattern="^[-\w\s]+(?:,[-\w\s]*)*$"
               (matChipInputTokenEnd)="add($event)"
               formArrayName="tags"
               required
        />
      </mat-chip-list>
      <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
        <mat-option *ngFor="let tag of filteredTags | async" [value]="tag">
          {{ tag }}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
  </div>
  ....
</form>

我无法弄清楚是什么问题......

标签: angularangular-material

解决方案


这是rxjs运算符的错误导入:

import {Observable} from 'rxjs/index';
import {map, startWith} from 'rxjs/internal/operators';

正确的:

import {Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';

推荐阅读