值 return 无法读取未定义的 属性 'value'
Value return Cannot read property 'value' of undefined
我是 angular 的超级新手,所以我不知道是否有人回答了这个问题。我查看了一些答案,但无法正确回答。抱歉,如果这个问题已经得到回答。
我有一个调用后端 Rest 的 Angular 服务 API
export class StudentService {
private studentUrl: string;
constructor(private httpClient: HttpClient) {
this.studentUrl = 'someurl';
}
public getTag(email: string): Observable < PayLoad > {
const params = new HttpParams().set("email", email);
return this.httpClient.get < PayLoad > (this.studentUrl.concat("Tag"), {
params
});
}
getCoursesForStudent(tag: string): Observable < CourseDto > {
const params = new HttpParams().set("tag", tag);
return this.httpClient.get < CourseDto > (this.studentUrl.concat('courses'), {
params
})
}
getStudentByEmail(email: string): Observable < any > {
const params = new HttpParams().set("email", email.toString());
return this.httpClient.get < Student > (this.studentUrl.concat('getstu'), {
params
})
}
}
而且我还有一个使用它的组件
export class StudentprofileComponent implements OnInit {
courses: Observable < CourseDto > ;
student: Student;
newstu: Student;
tag: PayLoad;
payload = PayLoad;
constructor(private studentservice: StudentService, private router: Router) {}
loadCourses() {
payload: new PayLoad();
const email = atob(localStorage.getItem('stuemail'));
this.studentservice.getTag(email).subscribe(data => {
this.tag = data,
console.log("data:" + data.value)
});
return this.studentservice.getCoursesForStudent(this.tag.value);
}
loadStudent() {
let email = atob(localStorage.getItem('email'));
return this.studentservice.getStudentByEmail(email.toString());
}
ngOnInit() {
this.loadStudent().subscribe(data => {
this.student = data
}, error =>
console.log(error));
this.courses = this.loadCourses();
}
}
问题是,我不断收到 TypeError Cannot read 属性 'value' of undefined。甚至数据也打印在控制台中。
这是一个异步调用。你不知道服务器什么时候会 return 这个 get-endpoint-
的答案
您使用函数 .subscribe() 订阅了通话。
在您订阅的那一刻,get 将尝试到达后端。
订阅函数中的所有内容都将在 returned 时执行。
//1.register subscription
this.studentservice.getTag(email).subscribe(
data=>{
//3. will be executed when server answers
this.tag = data ,
console.log("data:"+data.value)});
//2. Will return the value before the tag-object is set in subscribe
return this.studentservice.getCoursesForStudent(this.tag.value);
所以你遇到的问题是,当你调用 return 所在的行时,标签对象仍然未定义,因为订阅还没有 returned。
您可以尝试在订阅内执行 getCoursesForStudent,但这会使它变得更复杂。
您可以尝试使用 switchmap 在另一个完成时订阅 observable
https://www.learnrxjs.io/learn-rxjs/operators/transformation/switchmap
嵌套订阅是一种反模式,应该避免。尝试使用 switchMap 运算符来获取您需要的值。
export class StudentprofileComponent implements OnInit {
courses: CourseDto ; // Removed the Observable due to new subscription
student: Student;
// newstu: Student;
// tag: PayLoad;
// payload = PayLoad;
constructor(private studentservice: StudentService, private router: Router) {}
// loadCourses() {
// payload: new PayLoad();
// const email = atob(localStorage.getItem('stuemail'));
// this.studentservice.getTag(email).subscribe(data => {
// this.tag = data,
// console.log("data:" + data.value)
// });
// return this.studentservice.getCoursesForStudent(this.tag.value);
// }
// loadStudent() {
// let email = atob(localStorage.getItem('email'));
// return this.studentservice.getStudentByEmail(email.toString());
// }
ngOnInit() {
const email = atob(localStorage.getItem('email')).toString();
const stuEmail = atob(localStorage.getItem('stuemail')).toString();
this.studentservice.getStudentByEmail(email).subscribe(student => this.student = student);
this.studentservice.getTag(stuEmail).pipe(
switchMap(tag => this.studentservice.getCoursesForStudent(tag.value))
).subscribe(courses => this.courses = courses);
}
}
我是 angular 的超级新手,所以我不知道是否有人回答了这个问题。我查看了一些答案,但无法正确回答。抱歉,如果这个问题已经得到回答。
我有一个调用后端 Rest 的 Angular 服务 API
export class StudentService {
private studentUrl: string;
constructor(private httpClient: HttpClient) {
this.studentUrl = 'someurl';
}
public getTag(email: string): Observable < PayLoad > {
const params = new HttpParams().set("email", email);
return this.httpClient.get < PayLoad > (this.studentUrl.concat("Tag"), {
params
});
}
getCoursesForStudent(tag: string): Observable < CourseDto > {
const params = new HttpParams().set("tag", tag);
return this.httpClient.get < CourseDto > (this.studentUrl.concat('courses'), {
params
})
}
getStudentByEmail(email: string): Observable < any > {
const params = new HttpParams().set("email", email.toString());
return this.httpClient.get < Student > (this.studentUrl.concat('getstu'), {
params
})
}
}
而且我还有一个使用它的组件
export class StudentprofileComponent implements OnInit {
courses: Observable < CourseDto > ;
student: Student;
newstu: Student;
tag: PayLoad;
payload = PayLoad;
constructor(private studentservice: StudentService, private router: Router) {}
loadCourses() {
payload: new PayLoad();
const email = atob(localStorage.getItem('stuemail'));
this.studentservice.getTag(email).subscribe(data => {
this.tag = data,
console.log("data:" + data.value)
});
return this.studentservice.getCoursesForStudent(this.tag.value);
}
loadStudent() {
let email = atob(localStorage.getItem('email'));
return this.studentservice.getStudentByEmail(email.toString());
}
ngOnInit() {
this.loadStudent().subscribe(data => {
this.student = data
}, error =>
console.log(error));
this.courses = this.loadCourses();
}
}
问题是,我不断收到 TypeError Cannot read 属性 'value' of undefined。甚至数据也打印在控制台中。
这是一个异步调用。你不知道服务器什么时候会 return 这个 get-endpoint-
的答案您使用函数 .subscribe() 订阅了通话。 在您订阅的那一刻,get 将尝试到达后端。
订阅函数中的所有内容都将在 returned 时执行。
//1.register subscription
this.studentservice.getTag(email).subscribe(
data=>{
//3. will be executed when server answers
this.tag = data ,
console.log("data:"+data.value)});
//2. Will return the value before the tag-object is set in subscribe
return this.studentservice.getCoursesForStudent(this.tag.value);
所以你遇到的问题是,当你调用 return 所在的行时,标签对象仍然未定义,因为订阅还没有 returned。
您可以尝试在订阅内执行 getCoursesForStudent,但这会使它变得更复杂。
您可以尝试使用 switchmap 在另一个完成时订阅 observable https://www.learnrxjs.io/learn-rxjs/operators/transformation/switchmap
嵌套订阅是一种反模式,应该避免。尝试使用 switchMap 运算符来获取您需要的值。
export class StudentprofileComponent implements OnInit {
courses: CourseDto ; // Removed the Observable due to new subscription
student: Student;
// newstu: Student;
// tag: PayLoad;
// payload = PayLoad;
constructor(private studentservice: StudentService, private router: Router) {}
// loadCourses() {
// payload: new PayLoad();
// const email = atob(localStorage.getItem('stuemail'));
// this.studentservice.getTag(email).subscribe(data => {
// this.tag = data,
// console.log("data:" + data.value)
// });
// return this.studentservice.getCoursesForStudent(this.tag.value);
// }
// loadStudent() {
// let email = atob(localStorage.getItem('email'));
// return this.studentservice.getStudentByEmail(email.toString());
// }
ngOnInit() {
const email = atob(localStorage.getItem('email')).toString();
const stuEmail = atob(localStorage.getItem('stuemail')).toString();
this.studentservice.getStudentByEmail(email).subscribe(student => this.student = student);
this.studentservice.getTag(stuEmail).pipe(
switchMap(tag => this.studentservice.getCoursesForStudent(tag.value))
).subscribe(courses => this.courses = courses);
}
}