Угловой 6: невозможно прочитать свойство length of undefined

У меня действительно странная проблема. Я отправляю данные от родительского компонента к дочернему с помощью @Input, и я получаю эту ошибку, но когда я попытался распечатать значение в ngOnInit, я получил правильное значение, а не undefined. Данные в родительском компоненте определены, и я получаю значение в консоли, когда печатаю данные в родительском и дочернем компонентах, и я все равно получаю эту ошибку (даже если я получаю доступ к данным)

это скриншот ошибки и значение, которое я получил из console.info

Угловой 6: невозможно прочитать свойство length of undefinedУгловой 6: невозможно прочитать свойство length of undefined

соответствующий родительский html:

<quiz-course [quiz] = "currentUnitQuiz"></quiz-course>

родитель ts:

export class CoursePlayComponent implements OnInit {
  errorMessage: string;
  course: ICourse;
  courseId: number;

  // the current and prev quiz of this and prev unit (if there are)
  public currentUnitQuiz: IQuiz;
  public showQuiz: boolean;
  
  // .. more properties


  constructor(private courseService: CourseService,
      private route: ActivatedRoute,
      private router: Router,
      private userProgressService: UserProgressService) { }

  ngOnInit() {
      // save this course id from course-detail and get http request from the service
      this.courseId = JSON.parse(localStorage.getItem("courseId"));
      this.getCourse(this.courseId);
    }
    
  // Get course detail by id
  getCourse(id: number) {
      this.courseService.getCourse(id).subscribe(
          course => {
            this.course = course;
            
            // .. more code

            if (this.route.snapshot.firstChild.data.type == 'quiz') {
              this.getQuiz(this.currentUnitPos);
            }
          },
          error  => this.errorMessage = <any>error);
      }
      
      getQuiz(currentUnitPosition: number) {
      // .. more code
        this.showQuiz = true;
        this.currentUnitQuiz = this.course.units.find(u => u.position ===
        currentUnitPosition).quiz;
      }
 }

Обновлено: добавлен дополнительный код, чтобы было понятно. Я получаю ту же ошибку, когда пытаюсь получить доступ к длине, но я также могу распечатать и получить число, поэтому я не знаю, в чем проблема.

ребенок ts:

export class CourseQuizComponent implements OnInit {

  @Input() quiz: IQuiz;
  
  // 1 = show the first page. 2 = show questions page. 0 = show neither
  public currentQuestion: IQuestion;
  public currentIndex: number;
  public currentUnit: number;
  public userAnswers: number[] = [];
  public correctAnswers: number;

  constructor(private courseService: CourseService,
      private route: ActivatedRoute,
      private router: Router,
      private fb: FormBuilder) { }

  ngOnInit() {
    console.info("length in child: ", this.quiz.questions.length); // **NOT** undefined
    this.restartQuiz();
  }
  
    restartQuiz() {
    this.currentUnit = +this.route.snapshot.paramMap.get('unitId');
    this.correctAnswers = 0;

    for(let i = 0; i < this.quiz.questions.length; i++) {
      this.userAnswers[i] = 0;
    }

    this.getCurrentQuestion(0);
  }

}

интерфейсы:

export interface IQuiz {
  id: number;
  name: number;
  unit_id: number;
  unit_position: number;
  questions: IQuestion[];
}

export interface IQuestion {
  id: number;
  name: string;
  quiz_id: number;
  position: number;
  question: string;
  answer1: string;
  answer2: string;
  answer3: string;
  answer4: string;
  correct: number;
  selected: number;
}

И где вы пытаетесь получить доступ к свойству length, если оно не определено?

yannick 24.10.2018 16:05

в дочернем, но я получил длину в консоли, он напечатал 2 и строку после того, как напечатал эту ошибку. Добавлю скриншот

Ofir Sasson 24.10.2018 16:05

при добавлении компонента викторины? перед длиной, как эта викторина? .questions? .length в html

h_w 24.10.2018 16:08

Перейдите в класс IQuiz, предполагая, что questions является массивом, проверьте, правильно ли он инициализирован (например, questions = [])

Daniel C. 24.10.2018 16:09

questions определяется так: questions: IQuestion []; и я тоже определил IQuestions. Я добавил интерфейсы сейчас

Ofir Sasson 24.10.2018 16:12

Покажите, как вы пытаетесь получить к нему доступ в дочернем компоненте.

lealceldeiro 24.10.2018 16:12
and I get this error <= показать код, в котором возникает ошибка.
Igor 24.10.2018 16:12

он говорит, что в строке, когда я печатаю значение, но он печатает значение

Ofir Sasson 24.10.2018 16:13

Нет, трассировка стека утверждает, что это происходит в методе restartQuiz. Покажи этот код.

Igor 24.10.2018 16:15

Я добавил это. Я делаю то же самое и пытаюсь получить доступ к длине массива вопросов, но также я получаю длину в консоли из console.info

Ofir Sasson 24.10.2018 16:22

вам нужно инициировать переменную вашей викторины в родительском компоненте

Fateh Mohamed 24.10.2018 16:28

Я знаю, что у меня есть значения в родительском компоненте, потому что я попытался распечатать его и получил значение, а также я получаю значение в дочернем при печати с помощью console.info, поэтому странно, что я получаю эту ошибку, когда получаю данные с console.info

Ofir Sasson 24.10.2018 16:31

вы получаете currentUnitQuiz по наблюдаемой подписке?

Fateh Mohamed 24.10.2018 16:34

да, и я вижу данные, которые получаю в родительском компоненте. Там много нерелевантного кода, но я отредактирую вопрос и добавлю соответствующий код из родительского ts

Ofir Sasson 24.10.2018 16:36

удалить блок подписки и использовать асинхронный канал, чтобы избежать неопределенного случая <quiz-course [quiz] = "currentUnitQuizObservable | async"> </quiz-course>

Fateh Mohamed 24.10.2018 16:38

не сработало, теперь я получаю эту ошибку: Ошибка: InvalidPipeArgument: '[object Object]' для канала 'AsyncPipe'

Ofir Sasson 24.10.2018 16:50

Есть ли конкретная причина, по которой викторина относится к типу IQuiz, а не к типу Quiz, реализующему интерфейс?

Kevin McCann 05.07.2019 07:24
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
17
3 116
1

Ответы 1

это вводная информация для ребенка, поэтому лучше всего, чтобы избежать этой неопределенной проблемы, использовать лайфхук onchanges.

 import { OnChanges, SimpleChanges } from '@angular/core';

export class CourseQuizComponent implements OnInit, OnChanges {
  ngOnChanges(changes: SimpleChanges) {
   for (const prop of Object.keys(changes)) {
    const chng = changes[prop];
    if (prop === 'quiz') {
      this.quiz = chng.currentValue;
      // use this quiz variable in the restartQuiz() 
    }
  }
 }
 ngOnInit() {
   this.restartQuiz();
  }
}

попробуйте и дайте мне знать, работает ли это.

к сожалению, это не работает. Мне нужно вызвать restartQuiz, когда компонент начнет свою жизнь, поэтому мне тоже нужно изменить это и вызвать его в ngOnChanges? как насчет html-файла, содержащего данные из @Input?

Ofir Sasson 24.10.2018 18:16

Вы упомянули, что вам нужно вызвать restartQuiz () в oninit (). Это не изменится. Не вызывайте restartQuiz () в onchanges. но инициализируйте входную переменную викторины в onchanges (). Проще говоря, поскольку это дочерний компонент, onchanges будет гарантировать, что входная переменная будет иметь самое последнее значение после загрузки дочернего элемента. отредактировал ответ, чтобы избежать недоразумений.

reddevilzee 24.10.2018 18:29

Другие вопросы по теме