休息调用后数据未加载到数组中

时间:2017-10-01 08:17:33

标签: angular

我遇到了简单的Angular / Java应用程序的困难。在休息呼叫期间,我也在创建一个磁贴组件。正在重试数据 - 我可以在网络选项卡和后端日志中看到日志,但是没有创建Tile组件。这是代码:

main.grid.ts:

@Component({
  templateUrl: './main.html',
  selector: 'album-grid',
})
export class MainGrid implements OnInit {

  private tileDtos: TileDto [];
  private album: AlbumDto [];

  constructor(public dialog: MdDialog, private albumService: AlbumService, private tileUtils: TileUtils) {
    this.album=[];
    this.tileDtos=[];
  }

  ngOnInit(): void {
   this.albumService.getAllAlbums().subscribe(p => this.album = p); // here is the call to rest service
    console.log("@@@@@@@@@@@@@  "+ this.album.length); // this returns 0
    this.tileDtos = this.tileUtils.buildTile(this.album);
    console.log("@@@@@@@@@@@@@  "+ this.tileDtos.length); // this returns 0
  }

}

album.service.ts:

@Injectable()
export class AlbumService {
  private baseUrl = 'http://localhost:8080';

  constructor(private http: Http) {
  }

  getAllAlbums(): Observable<AlbumDto[]> {
    let getUrl = `${this.baseUrl}/getAllAlbums`;
    return this.http.get(getUrl, {headers: AlbumService.getHeaders()}).map(mapAlbums);
  }

  private static getHeaders() {
    let headers = new Headers();
    headers.append('Accept', 'application/json');
    return headers;
  }
}

function mapAlbums(response: Response): AlbumDto[] {
  let json = response.json();
  let album: AlbumDto[] = json.map(toAlbum);
  return album;
}

function toAlbum(r: any): AlbumDto {
  let album = <AlbumDto>({
    id: r.id,
    albumName: r.albumName,
    owner: r.owner,
    images: r.images,
  });
  console.log("album: ",album);
  return album;
}

在前端的日志中我可以看到:

@@@@@@@@@@@@@  0
Building tile
@@@@@@@@@@@@@  0
album: //here I'm seeing full album json populated as it should be.

编辑。

为了缩小问题范围,据我所知,问题在于Main.Grid.ts中的加载顺序。正如我在日志中注意到的那样,在创建tile元素的代码之后会触发其余的调用。我试过使用硬编码的json对象,它已正确加载。

2 个答案:

答案 0 :(得分:2)

您尝试在更新之前记录并使用ngOnInit(): void { this.albumService.getAllAlbums().subscribe(p => this.album = p); // here is the call to rest service console.log("@@@@@@@@@@@@@ "+ this.album.length); // this returns this.tileDtos = this.tileUtils.buildTile(this.album); console.log("@@@@@@@@@@@@@ "+ this.tileDtos.length); // this returns 0 } 的更新值。再看一下上面的代码:

p => this.albums = p

网络调用完成后,代码this.album将以异步方式运行 。在调用此异步操作后,您立即尝试使用尚未更新的this.album。这是一个细分:

  1. 您指示Angular进行网络调用,为其提供一个在返回数据后调用的函数。
  2. 在Angular有机会发出请求之前,您尝试访问尚未更新的this.album,并保持为空数组。
  3. 一段时间后,Angular会返回数据并调用您的回调函数,该函数会更新this.tileDtos更新ngOnInit(): void { this.albumService.getAllAlbums().subscribe(p => { this.album = p; // here is the call to rest service console.log("@@@@@@@@@@@@@ "+ this.album.length); // this returns this.tileDtos = this.tileUtils.buildTile(this.album); console.log("@@@@@@@@@@@@@ "+ this.tileDtos.length); // this returns 0 }); }
  4. 要解决此问题,您需要以正确的顺序运行相关代码。 e.g:

    this.album

    如您所见,这将确保在尝试使用它来更新组件之前正确设置connect(ui->celsiusDial, SIGNAL(valueChanged(int)), ui->celsiusLcd,SLOT(display(int))); 的值。

答案 1 :(得分:0)

是否:

this.albumService.getAllAlbums()。subscribe(p =&gt; this.album = p);

回报承诺?你需要将它附加到.then()并在那里工作。