Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 未定义的数组,尽管它在dom 6中呈现_Angular_Typescript_Rxjs_Undefined - Fatal编程技术网

Angular 未定义的数组,尽管它在dom 6中呈现

Angular 未定义的数组,尽管它在dom 6中呈现,angular,typescript,rxjs,undefined,Angular,Typescript,Rxjs,Undefined,这是我的Books组件,它包含我试图控制日志的Books数组。它记录一个未定义的,但在使用*ngFor后,它在DOM中正确显示 import { Component, OnInit } from '@angular/core'; import { BooksService } from '../shared/books.service'; import { ActivatedRoute, Params } from '@angular/router'; import { Book } from

这是我的Books组件,它包含我试图控制日志的Books数组。它记录一个未定义的
,但在使用
*ngFor
后,它在DOM中正确显示

import { Component, OnInit } from '@angular/core';
import { BooksService } from '../shared/books.service';
import { ActivatedRoute, Params } from '@angular/router';
import { Book } from './book.model';

@Component({
  selector: 'app-books',
  templateUrl: './books.component.html',
  styleUrls: ['./books.component.scss']
})
export class BooksComponent implements OnInit {
  books: Book[];
  filteredBooks: Book[];
  id: string;

  constructor(
    private booksService: BooksService,
    private route: ActivatedRoute
  ) {}

  ngOnInit() {

    this.booksService.getJson()
      .subscribe(response => (
        this.books = response.json().books)
      );

      console.log(this.books) //undefined;

    this.route.params.subscribe((params: Params) => {
      this.id = params['id'];
    });
    const filter = this.books.filter(book => book.author === this.id);
    console.log(filter);
  }
}

角度渲染您的
书籍
多次。开始时,角度也是
未定义的


尝试将您的
过滤器
代码放入
订阅
-块

这部分代码有问题:

this.booksService.getJson()
  .subscribe(response => (
    this.books = response.json().books)
  );

  console.log(this.books) //undefined;
HTTP调用是异步的,因此
.subscribe()
中的代码将在
console.log(this.books)//undefined之后运行

console.log
放入
.subscribe()方法中

this.booksService.getJson()
      .subscribe(response => (
        this.books = response.json().books);
        console.log(this.books) //undefined;
      );
实际上-您也在从
route.params
读取
id
-这也是一项异步任务。在这种情况下,您应该将
bookservice.getJSON()
stream与
route.params
stream组合,并执行类似操作:

Observable.combineLatest(
    this.route.params,    //1st stream
    this.booksService.getJson().map(res => res.json().books) //2nd stream   
)
.do((values: any[]) => {
    const id = values[0]['id']; //params from 1st stream
    const allBooks = values[1];        //already mapped books from 2nd stream

    this.filteredBooks = allBooks.filter(book => book.author === id);

}).subscribe();

欢迎来到堆栈溢出!我在代码中看到的问题是,您试图在获取books数组之前打印它

bookservice
调用的函数
getJson()
是一个异步调用。也就是说,我们不知道这个函数获取books数组需要多长时间(在某些情况下可能会失败)

如果您只想打印图书列表,可以这样做(注意,我添加了一个错误块来处理错误):

此外,在您的模板(html)中,您还必须添加一个
*ngIf
,然后才能反复阅读以下书籍:

<div *ngIf="books">
  <div *ngFor="let book of books">
    <div>{{book.name || 'unknown'}}</div>
  </div>
</div>

{{book.name | |'未知'}
但是,我强烈建议您阅读一下这些来源中的承诺链接承诺.race甚至回调函数。您也可以自由地在其他地方引用,但在我看来,下面的第一个站点(MDN)是引用任何与javascript相关的内容的好地方:)


您希望您的服务立即返回值吗?您正在subscribe write
console.log(this.books)
中进行ajax调用,然后它将工作,但在subscribe之外它将不工作阅读JavaScript中的异步代码。您正在进行一个异步服务调用,并在从服务器获得响应后的某个时间将响应分配给this.books
。同时,浏览器将立即解析该行,这将导致未定义
<div *ngIf="books">
  <div *ngFor="let book of books">
    <div>{{book.name || 'unknown'}}</div>
  </div>
</div>