【问题标题】:subscribe inside foreach returning undefined在 foreach 中订阅返回 undefined
【发布时间】:2021-06-03 05:43:50
【问题描述】:

抱歉,我仍然是 Angular 的初学者,我不明白异步是如何工作的。我编写了以下代码,但确实出现错误:GET https://localhost:44353/api/ecams/id/undefined 400["The value 'undefined' is not valid."]。我的猜测是来自服务器的答案来得不够快,以至于它可以开始下一条指令。我应该如何进行?

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { Exam } from '../_models/exam';
import { IndividualSession } from '../_models/individual-session';
import { IndividualSessionData } from '../_models/individual-session-data';
import { Session } from '../_models/session';
import { User } from '../_models/user';
import { AccountService } from '../_services/account.service';
import { ExamsService } from '../_services/exams.service';
import { IndividualSessionService } from '../_services/individual-session.service';
import { SessionService } from '../_services/session.service';
import { UsersService } from '../_services/users.service';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
  currentUser$: Observable<User>;
  user: User;
  userId: number;
  individualSessionsData: IndividualSessionData[] = [];
  
  tempIndividualSessionData: IndividualSessionData = {} as IndividualSessionData;

  constructor(private accountService: AccountService,
    private individualSessionService: IndividualSessionService,
    private userService: UsersService,
    private examService: ExamsService,
    private sessionService: SessionService) {
       this.tempIndividualSessionData.exam = {} as Exam;
       this.tempIndividualSessionData.individualSession = new IndividualSession();
       this.tempIndividualSessionData.session = {} as Session;
       this.getCurrentUserData();
      }

  ngOnInit(): void {

  }

  onRowClick(){
    
  }

  logout() {
    this.accountService.logout();
  }

  private getCurrentUserData() {
    this.currentUser$ = this.accountService.currentUser$;
    this.currentUser$.subscribe(user => {
      if (!!user) {
        this.user = user;
        this.loadUser(this.user.email);
      }
    });
  }

  loadUser(email: string) {
    this.userService.getUser(email).subscribe(user => {
      if(!!user) {
        this.user = user;
        this.loadId(this.user.email);
      }
    })
  }

  loadId(email: string) {
    this.userService.getId(email).subscribe(id => {
      if(!!id) {
        this.userId = id;
        this.loadIndividualSessions(this.userId);
      }
    })
  }

  loadIndividualSessions(id: number) {
    this.individualSessionService.getIndividualSessions(id).subscribe(sessions => {
      if(!!sessions) {
        sessions.forEach(session => {
          this.tempIndividualSessionData.individualSession = session;
          this.loadSession(session.sessionId);
        });
      }
    })
  }

  loadSession(id: number) {
    this.sessionService.getSession(id).subscribe(session => {
      if(!!session) {
        this.tempIndividualSessionData.session = session;
        this.loadExam(session.examId);
      }
    })
  }

  loadExam(id: number) {
    this.examService.getExamById(id).subscribe(exam => {
      if(!!exam) {
        this.tempIndividualSessionData.exam = exam;
        this.individualSessionsData.push(this.tempIndividualSessionData);
      }
    })
  }
}

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { environment } from 'src/environments/environment';
import { Exam } from '../_models/exam';
import { Question } from '../_models/question';

@Injectable({
  providedIn: 'root'
})
export class ExamsService {
  baseUrl = environment.apiUrl;
  currentExam: Exam;
  answeredQuestions: Question[];
  correctAnswers: number[];
  currentMark: number;

  constructor(private http: HttpClient) { }

  getExams() {
    return this.http.get<Exam[]>(this.baseUrl + 'exams');
  }

  getExam(title: string){
    return this.http.get<Exam>(this.baseUrl + 'exams/title/' + title); 
  }

   getExamById(id: number){
     return this.http.get<Exam>(this.baseUrl + 'exams/id/' + id); 
   }

}

提前感谢您,祝您编码愉快!

【问题讨论】:

  • 你为什么使用“!!exam”或类似的?你可以调用 if (exam) 来检查它是 undefined 还是 null。
  • 进一步:您收到 400 错误,因为您对 API 的请求是错误的。 URL 包含“未定义”。哪些方法会向该 URL 发出 HTTP 请求?
  • this.examService.getExamById(id).subscribe(exam => ...) 是您要的。网址应该类似于localhost:44353/api/exams/id/1
  • 你能编辑你的帖子并添加examService.getExamById()的代码吗?
  • 刚刚做了

标签: angular typescript asynchronous


【解决方案1】:

HTTP code 400错误说明你的请求有误:

https://localhost:44353/api/ecams/id/undefined

我看清楚了三点:

  1. 有一个错字:应该是“exams”而不是“ecams”
  2. “未定义”表示您尝试附加的值未定义。
  3. 如果您不是 API 的开发人员并且它是一个 REST API,我认为 URL 应该是:https://localhost:44353/api/exams/1/something
  4. 建议检查方法的参数是否未定义或为空。

我假设,loadExam() 中的 session.examId 至少有一次未定义。尝试将您的代码更改为:


loadExam(id: number) {
    if (id){
        this.examService.getExamById(id).subscribe(exam => {
          if(exam) {
            this.tempIndividualSessionData.exam = exam;
            this.individualSessionsData.push(this.tempIndividualSessionData);
          }
        });
    } else {
        console.error("Exam id is null or undefined.");
    }
  }

您可以在 sessions.forEach() 调用中添加console.log(session); 行,并检查是否有任何会话没有examId。此外,您可以在浏览器中打开开发工具并在向 API 发出请求时检查网络流量。请求有效吗?如果是,则捕获结果时出错。如果不是,您的请求中有错误。再次检查您尝试发送的参数。

【讨论】:

  • 好的,刚刚发现问题所在。显然 session.examId 以 session.questionnaireId 的形式出现在请求中。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 1970-01-01
  • 2017-03-26
相关资源
最近更新 更多