值返回无法读取未定义的属性“值”

时间:2020-07-21 05:42:24

标签: angular typescript rest typeerror angular9

我对Angle非常陌生,所以我不知道是否回答了。我调查了一些答案,但无法正确解决。抱歉,如果已经回答。

我有一个调用后端Rest API的Angular服务

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无法读取未定义的属性“值” 。甚至数据也会在控制台中打印。

This is the TypeError

Error Line

2 个答案:

答案 0 :(得分:3)

嵌套订阅是一种反模式,应避免使用。尝试使用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);
        
    }

}

答案 1 :(得分:1)

这是一个异步电话。您不知道服务器何时将返回此get-endpoint-

的答案。

您使用.subscribe()函数订阅了呼叫。 在您订阅时,获取将尝试到达后端。

他的订阅函数中的所有内容都将在返回get时执行。

//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);

因此,您遇到的问题是,当您调用返回所在的行时,标记对象仍未定义,因为订阅尚未返回。

您可以尝试在订阅中执行getCoursesForStudent,但这会使它更加复杂。

当另一个完成时,您可以尝试使用switchmap订阅可观察对象 https://www.learnrxjs.io/learn-rxjs/operators/transformation/switchmap