Angular 4:InvalidPipeArgument:管道“AsyncPipe”的“[object Object]”

问题描述 投票:0回答:7

我需要你的帮助,我正在尝试显示来自我的 firebase 的一些数据,但它给我带来了类似

InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'
的错误。


我的服务是:

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';

@Injectable()
export class MoviesService {

  constructor(private db: AngularFireDatabase) {}
  get = () => this.db.list('/movies');
}

这是我的组件:

import { Component, OnInit } from '@angular/core';
import { MoviesService } from './movies.service';

@Component({
  selector: 'app-movies',
  templateUrl: './movies.component.html',
  styleUrls: ['./movies.component.css']
})
export class MoviesComponent implements OnInit {
  movies: any[];

  constructor(private moviesDb: MoviesService) { }

  ngOnInit() {
    this.moviesDb.get().subscribe((snaps) => {
      snaps.forEach((snap) => {
        this.movies = snap;
        console.log(this.movies);
      });
   });
 }
}

还有哈巴狗妈妈:

ul
  li(*ngFor='let movie of (movies | async)')
    | {{ movie.title | async }}
angular pipe pug observable angularfire2
7个回答
51
投票

async
用于绑定到 Observables 和 Promises,但看起来你正在绑定到一个常规对象。您只需删除两个
async
关键字就可以了。


23
投票

当您在模板中使用异步,但引用的对象不是 Observable 时,您会收到此消息。

为了举例,假设我的类中有这些属性:

job:Job
job$:Observable<Job>

然后在我的模板中,我这样引用它:

{{job | async }}

而不是:

{{job$ | async }}

如果使用异步管道,则不需要 job:Job 属性,但它可以说明错误的原因。


19
投票

在您的 MoviesService 中,您应该导入 FirebaseListObservable 以便定义返回类型

FirebaseListObservable<any[]>

import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';

那么 get() 方法应该是这样的-

get (): FirebaseListObservable<any[]>{
        return this.db.list('/movies');
    }

此 get() 方法将返回电影列表的 FirebaseListObervable

在你的 MoviesComponent 中应该看起来像这样

export class MoviesComponent implements OnInit {
  movies: any[];

  constructor(private moviesDb: MoviesService) { }

  ngOnInit() {
    this.moviesDb.get().subscribe((snaps) => {
       this.movies = snaps;
   });
 }
}

然后你可以轻松地迭代电影而无需异步管道,因为电影[]数据不是可观察类型,你的html应该是这样的

ul
  li(*ngFor='let movie of movies')
    {{ movie.title }}

如果您将电影声明为

movies: FirebaseListObservable<any[]>;

那么您只需致电

movies: FirebaseListObservable<any[]>;
ngOnInit() {
    this.movies = this.moviesDb.get();
}

你的html应该是这样的

ul
  li(*ngFor='let movie of movies | async')
    {{ movie.title }}

8
投票

我找到了另一种获取数据的解决方案。根据文档请检查文档链接

在服务文件中添加以下内容。

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';

@Injectable()
export class MoviesService {

  constructor(private db: AngularFireDatabase) {}
  getMovies() {
    this.db.list('/movies').valueChanges();
  }
}

在组件中添加以下内容。

import { Component, OnInit } from '@angular/core';
import { MoviesService } from './movies.service';

@Component({
  selector: 'app-movies',
  templateUrl: './movies.component.html',
  styleUrls: ['./movies.component.css']
})
export class MoviesComponent implements OnInit {
  movies$;

  constructor(private moviesDb: MoviesService) { 
   this.movies$ = moviesDb.getMovies();
 }

在您的 html 文件中添加以下内容。

<li  *ngFor="let m of movies$ | async">{{ m.name }} </li>

0
投票

您应该将管道添加到

interpolation
而不是
ngFor

ul
  li(*ngFor='let movie of (movies)') ///////////removed here///////////////////
    | {{ movie.title | async }}

参考文档


0
投票

好吧,我现在遇到了类似的问题,我解决了,所以让我解释一下你可以做什么,但首先我不知道你使用的是哪个版本的 Angular,所以方法可能不同,我在下面添加我的设置版本

Angular CLI: 13.3.1
Node: 16.14.2
Package Manager: npm 8.5.0
OS: win32 x64

Angular: 13.3.1
... animations, cli, common, compiler, compiler-cli, core, forms    
... platform-browser, platform-browser-dynamic, router

Package                         Version

    @angular-devkit/architect       0.1303.1
@angular-devkit/build-angular   13.3.1
@angular-devkit/core            13.3.1
@angular-devkit/schematics      13.3.1
@angular/fire                   7.3.0
@schematics/angular             13.3.1
rxjs                            7.5.5
typescript                      4.6.3

1 第一个更改是您的服务文件,将其更改为

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';

    @Injectable()
    export class MoviesService {

      constructor(private db: AngularFireDatabase) {}
      get = () => this.db.list('/movies');
    }

对此,

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';

    @Injectable()
    export class MoviesService {

      constructor(private db: AngularFireDatabase) {}
      get = () => this.db.list('/movies');
    }

注意:- 不要忘记从正确的模块导入 Observable

然后从此更改您的组件

    import { Injectable } from '@angular/core';
    import { AngularFireDatabase } from 'angularfire2/database';

    @Injectable()
    export class MoviesService {

      constructor(private db: AngularFireDatabase) {}
      get(): Observable<any[]>{
          return this.db.list('/movies')
      } 
    }

对于这样的事情

    import { Injectable } from '@angular/core';
    import { AngularFireDatabase } from 'angularfire2/database';

    @Injectable()
    export class MoviesService {

      constructor(private db: AngularFireDatabase) {}
      get(): Observable<any[]>{
          return this.db.list('/movies')
      } 
    }

还有你的最后一个文件

import { Component, OnInit } from '@angular/core';
import { MoviesService } from './movies.service';

    @Component({
      selector: 'app-movies',
      templateUrl: './movies.component.html',
      styleUrls: ['./movies.component.css']
    })
    export class MoviesComponent implements OnInit {
      movies: any[];

      constructor(private moviesDb: MoviesService) { }

      ngOnInit() {
        this.moviesDb.get().subscribe((snaps) => {
          snaps.forEach((snap) => {
            this.movies = snap;
            console.log(this.movies);
          });
       });
     }
    }

对此

import { Component, OnInit } from '@angular/core';
import { MoviesService } from './movies.service';

    @Component({
      selector: 'app-movies',
      templateUrl: './movies.component.html',
      styleUrls: ['./movies.component.css']
    })
    export class MoviesComponent implements OnInit {
      movies: any[];

      constructor(private moviesDb: MoviesService) { }

      ngOnInit() {
        this.moviesDb.get().subscribe((snaps) => {
          snaps.forEach((snap) => {
            this.movies = snap;
            console.log(this.movies);
          });
       });
     }
    }

我不是专业人士,但我用这种方式解决了它,希望它也适合你


0
投票

可观察量 > 信号

如果您已将代码从使用

import { Component, OnInit } from '@angular/core';
import { MoviesService } from './movies.service';

    @Component({
      selector: 'app-movies',
      templateUrl: './movies.component.html',
      styleUrls: ['./movies.component.css']
    })
    export class MoviesComponent implements OnInit {
      movies$: any;

      constructor(private moviesDb: MoviesService) { }

      ngOnInit() {
        this.movies$ = this.moviesDb.get()
        .subscribe((snaps) => {
          snaps.forEach((snap) => {
            this.movies$ = snap;
            console.log(this.movies$);
          });
       });
     }
    }
转换为
import { Component, OnInit } from '@angular/core';
import { MoviesService } from './movies.service';

    @Component({
      selector: 'app-movies',
      templateUrl: './movies.component.html',
      styleUrls: ['./movies.component.css']
    })
    export class MoviesComponent implements OnInit {
      movies$: any;

      constructor(private moviesDb: MoviesService) { }

      ngOnInit() {
        this.movies$ = this.moviesDb.get()
        .subscribe((snaps) => {
          snaps.forEach((snap) => {
            this.movies$ = snap;
            console.log(this.movies$);
          });
       });
     }
    }
,您可能会遇到以下错误变体:

ul
   li(*ngFor='let movie of (movies | async)')
      | {{ movie.title | async }}

“本机代码”部分乍一看有点吓人,但它只是带有唯一符号的信号的字符串表示形式。

只需单击错误消息中与您的代码类似的第一行代码,即可找到模板中您切换到使用信号但未更新

ul
   li(*ngFor='let movie of (movies | async)')
      | {{ movie.title | async }}
管道的位置。

所以之前您可能已经:

ul
    li(*ngFor='let movie of (movies | async)')
        | {{ movie.title }}

现在作为一个信号应该是:

Observable
© www.soinside.com 2019 - 2024. All rights reserved.