У меня действительно странная проблема. Я отправляю данные от родительского компонента к дочернему с помощью @Input, и я получаю эту ошибку, но когда я попытался распечатать значение в ngOnInit, я получил правильное значение, а не undefined. Данные в родительском компоненте определены, и я получаю значение в консоли, когда печатаю данные в родительском и дочернем компонентах, и я все равно получаю эту ошибку (даже если я получаю доступ к данным)
это скриншот ошибки и значение, которое я получил из console.info
соответствующий родительский 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;
}в дочернем, но я получил длину в консоли, он напечатал 2 и строку после того, как напечатал эту ошибку. Добавлю скриншот
при добавлении компонента викторины? перед длиной, как эта викторина? .questions? .length в html
Перейдите в класс IQuiz, предполагая, что questions является массивом, проверьте, правильно ли он инициализирован (например, questions = [])
questions определяется так: questions: IQuestion []; и я тоже определил IQuestions. Я добавил интерфейсы сейчас
Покажите, как вы пытаетесь получить к нему доступ в дочернем компоненте.
and I get this error <= показать код, в котором возникает ошибка.
он говорит, что в строке, когда я печатаю значение, но он печатает значение
Нет, трассировка стека утверждает, что это происходит в методе restartQuiz. Покажи этот код.
Я добавил это. Я делаю то же самое и пытаюсь получить доступ к длине массива вопросов, но также я получаю длину в консоли из console.info
вам нужно инициировать переменную вашей викторины в родительском компоненте
Я знаю, что у меня есть значения в родительском компоненте, потому что я попытался распечатать его и получил значение, а также я получаю значение в дочернем при печати с помощью console.info, поэтому странно, что я получаю эту ошибку, когда получаю данные с console.info
вы получаете currentUnitQuiz по наблюдаемой подписке?
да, и я вижу данные, которые получаю в родительском компоненте. Там много нерелевантного кода, но я отредактирую вопрос и добавлю соответствующий код из родительского ts
удалить блок подписки и использовать асинхронный канал, чтобы избежать неопределенного случая <quiz-course [quiz] = "currentUnitQuizObservable | async"> </quiz-course>
не сработало, теперь я получаю эту ошибку: Ошибка: InvalidPipeArgument: '[object Object]' для канала 'AsyncPipe'
Есть ли конкретная причина, по которой викторина относится к типу IQuiz, а не к типу Quiz, реализующему интерфейс?





это вводная информация для ребенка, поэтому лучше всего, чтобы избежать этой неопределенной проблемы, использовать лайфхук 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?
Вы упомянули, что вам нужно вызвать restartQuiz () в oninit (). Это не изменится. Не вызывайте restartQuiz () в onchanges. но инициализируйте входную переменную викторины в onchanges (). Проще говоря, поскольку это дочерний компонент, onchanges будет гарантировать, что входная переменная будет иметь самое последнее значение после загрузки дочернего элемента. отредактировал ответ, чтобы избежать недоразумений.
И где вы пытаетесь получить доступ к свойству length, если оно не определено?