没有在Observable <>订阅中分配实例变量吗?

时间:2019-02-20 05:08:00

标签: angular typescript angular-in-memory-web-api

从Obersavable进行订阅时,出于某种原因,我的游戏数组未分配,即使我确定从服务器获得了正确的数据(数组)。

这是我的game.service.ts:

vignesh@vignesh-ThinkPad-E470 ~/go-book/src/github.com/my_fabric $ go build asd.go 
# command-line-arguments
./asd.go:25:29: cannot use "github.com/my_fabric/vendor/github.com/my_fabric/go-connections/nat".PortSet literal (type "github.com/my_fabric/vendor/github.com/my_fabric/go-connections/nat".PortSet) as type "github.com/docker/docker/vendor/github.com/docker/go-connections/nat".PortSet in field value

这是我的 games.component.ts:

import { Injectable } from '@angular/core';
import { Game } from '../models/game';
import { of, Observable } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';
import { NGXLogger } from 'ngx-logger';

@Injectable({
  providedIn: 'root'
})
export class GameService {
  private gamesUrl: string = 'api/games';

  constructor(private http: HttpClient, private logger: NGXLogger) { }

  getGames(): Observable<Game[]> {
    return this.http.get<Game[]>(this.gamesUrl);
  }

  getGame(id: number): Observable<Game> {
    const url: string = (`${this.gamesUrl}/${id}`);
    return this.http.get<Game>(url).pipe(tap(_ => this.logger.debug(`fetched game id=${id}`)), catchError(this.handleError<Game>(`getGame id=${id}`)));
  }

  log (operation: string) {
    console.log(operation);
  }

    /**
   * Handle Http operation that failed.
   * Let the app continue.
   * @param operation - name of the operation that failed
   * @param result - optional value to return as the observable result
   */
  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {

      console.error(error); // log to console instead
      this.logger.debug(`${operation} failed: ${error.message}`);
      return of(result as T);
    };
  }
}

您可以看到,我正在 games.component.ts 中呼叫 getGames ,其中 game.service.ts 正在将响应(可观察到的)返回。

由于某种原因,subscribe(games => this.games = games)不起作用,并且我对游戏实例变量进行了“未定义”。 我肯定会得到正确的响应,因为 subscribe(games => console.log(games))不会显示“ undefined”,而是显示一组对象。

为什么不分配我的实例变量?

修改: 如果我确实订阅,这是console.log中的输出(游戏=> console.log(游戏))

enter image description here

修改: 如果执行以下操作,则控制台日志正确。但是,如果我在其外部引用“游戏”数组,则会再次无法定义:

import { Component, OnInit } from '@angular/core';
import { Game } from '../../models/game';
import { GameService } from 'src/app/services/game.service';
import { Observable } from 'rxjs';

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

  constructor(private gameService: GameService) { 
  }

  ngOnInit() {
    this.getGames();
  }

  getGames(): void {
    this.gameService.getGames().subscribe(games => this.games = games);
    console.log(`games: ${this.games}`);
  }

  getGame(id: number): Observable<Game> {
    return this.gameService.getGame(id);
  }
}

编辑:已解决-谢谢dileepkumar jami 解决方法是删除$符号和'|异步”在我的模板中:

  getGames(): void {
    this.gameService.getGames().subscribe((games) => {
      this.games = games;
      console.log(`games: ${this.games}`);
    });
    console.log(`all games: ${this.games}`); //this is undefined
  }

<li *ngFor="let game of games$ | async">{{game.title}}</li>

3 个答案:

答案 0 :(得分:1)

  1.    getGames(): void { 
  2.      this.gameService.getGames().subscribe((games) => {
  3.        this.games = games;
  4.        console.log(`games: ${this.games}`);
  5.      });
  6.      console.log(`all games: ${this.games}`); //this is undefined
  7. }

我为您的代码行编号。

如预期的那样,the line6将返回undefined

line 2 to line 5中的代码需要一些时间才能完成,因为它具有API调用。

由于 JavaScript 是异步的,因此它不会等待代码(从第2行到第5行)完成。  它开始执行line6。但是,到那时,this.gamesundefined

即使您在浏览器控制台中看到,也将首先看到line6的输出,然后您可以看到line4

您可以执行以下代码块来查看javascript如何异步工作

function myFunction() {
  console.log('Hello');
}

setTimeout(myFunction, 3000);
console.log('hi');
As you can see, even though console.log('hi'); was written after setTimeout(myFunction, 3000);, hi would be printed first and then hello.

<p> So, javascript did not wait for the setTimeout(myFunction, 3000); to be finished and it started to execute the next line
</p>

编辑:已解决-谢谢dileepkumar jami 解决方法是删除$符号和'|异步”在我的模板中:

<li *ngFor="let game of games$ | async">{{game.title}}</li>

<li *ngFor="let game of games">{{game.title}}</li>

答案 1 :(得分:0)

尝试一下

getGames(): void {
    this.gameService.getGames().subscribe(games => {
      this.games = games;
      console.log(`games: ${this.games}`);
    );   

}

答案 2 :(得分:0)

您可以尝试在console.log(games: ${this.games});中访问订阅箭头功能内的游戏数组。服务返回响应之前。

 this.gameService.getGames().subscribe((games) =>  {
   this.games = games;
   console.log(`games: ${this.games}`);
 });

一旦分配了游戏属性,您就可以在组件中任意位置访问该值。仍然无法访问该值,那么您应该检查控制台中是否有任何错误。

更新 Javascript是异步的,它不会等待您的服务完成以执行其他代码,在您console.log()中的情况getGames中,您的this.games首先执行,然后调用订阅。因此undefined的值为getGames(): void { this.gameService.getGames().subscribe((games) => { this.games = games; console.log(`games: ${this.games}`); }); console.log(`all games: ${this.games}`); //this is undefined }

#include <string>
class Student{
    public:
        int studentID;
        std::string studentName;
        int currentEnrollment;
        void setName(std::string name);
        std::string getName();
};
Student AddStudent(Student *newStudent, int &countStudent, int &numStudent);
Student IncreasingSize(Student *newStudent, int oldSize, int newSize);