订阅端点后的未定义值

时间:2019-06-11 12:00:27

标签: angular

当我尝试订阅服务文件正在传递的响应时,得到一个未定义的值

这是我的代码

service.ts

getUserDetails(): Observable<GetUserByIdModel> {
  const token = this._storeService.getStoredData().id_token;
  const candidateId = this._storeService.getStoredData().profile.CandidateId;
  const headers = new HttpHeaders()
    .set('Authorization', `Bearer ${token}`)
    .set('Content-Type', 'application/json');
  const options = { headers: headers };
  const url = `${this.candidateUrl}/Get/${candidateId}`;
  this._http.get<GetUserByIdModel>(url, options).subscribe((resp) => {
    this.userDetails = {
      firstname: resp.firstname,
      lastname: resp.lastname,
      nationalityId: resp.nationalityId,
      identityTypeId: resp.identityTypeId,
      identityValue: resp.identityValue,
      titleId: resp.titleId,
      genderId: resp.genderId,
      candidateContactChannels: [
        { type: 1, value: resp.candidateContactChannels[0].value },
        { type: 2, value: resp.candidateContactChannels[1].value }
      ],
    };
    console.log(this.userDetails);
  })

  return new Observable((observer) => {
    observer.next(this.userDetails);
    observer.complete();
  });
}

component.ts

ngOnInit() {
  this._loader.start();
  this._profileService.getUserDetails().subscribe((resp) => {
    this.user = resp;
    console.log(this.user);
    this._loader.stop();
  }, (error) => {
    this._loader.stop();
    this._errorService.openErrorPopup('Failed to get user data.');
  });
}

我指的未定义值在 component.ts 文件console.log(this.user);中,该服务中的console.log正确显示了填充的数据

2 个答案:

答案 0 :(得分:1)

this.http.get()是异步调用。在调用结束之前,您将返回可观察对象。

相反,您只需定义并传递回调函数,

ngOnInit() {
  this._loader.start();
  this._profileService.getUserDetails((resp) => {
    this.user = resp;
    console.log(this.user);
    this._loader.stop()
  }, (err) => {
    this._loader.stop();
    this._errorService.openErrorPopup('Failed to get user data.');
  })
}

在使用中,

getUserDetails(callback, err): void {
  const token = this._storeService.getStoredData().id_token;
  const candidateId = this._storeService.getStoredData().profile.CandidateId;
  const headers = new HttpHeaders()
    .set('Authorization', `Bearer ${token}`)
    .set('Content-Type', 'application/json');
  const options = { headers: headers };
  const url = `${this.candidateUrl}/Get/${candidateId}`;
  this._http.get<GetUserByIdModel>(url, options).subscribe((resp) => {
    this.userDetails = {
      firstname: resp.firstname,
      lastname: resp.lastname,
      nationalityId: resp.nationalityId,
      identityTypeId: resp.identityTypeId,
      identityValue: resp.identityValue,
      titleId: resp.titleId,
      genderId: resp.genderId,
      candidateContactChannels: [
        { type: 1, value: resp.candidateContactChannels[0].value },
        { type: 2, value: resp.candidateContactChannels[1].value }
      ],
    };
    callback(this.userDetails);
  }, () => {
     err();
  })
}

答案 1 :(得分:1)

您使用的RxJ错误。在您的服务中,您已经具有可以返回到控制器的可观察对象,为什么还要订阅服务,然后创建并返回一个新的可观察对象?

在您的情况下,这表示类似以下内容:

service.ts

getUserDetails(): Observable<GetUserByIdModel> {
  const token = this._storeService.getStoredData().id_token;
  const candidateId = this._storeService.getStoredData().profile.CandidateId;
  const headers = new HttpHeaders()
    .set('Authorization', `Bearer ${token}`)
    .set('Content-Type', 'application/json');
  const options = { headers: headers };
  const url = `${this.candidateUrl}/Get/${candidateId}`;

  return this._http.get<GetUserByIdModel>(url, options).pipe(
    map((resp) => 
      {
        firstname: resp.firstname,
        lastname: resp.lastname,
        nationalityId: resp.nationalityId,
        identityTypeId: resp.identityTypeId,
        identityValue: resp.identityValue,
        titleId: resp.titleId,
        genderId: resp.genderId,
        candidateContactChannels: [
          { type: 1, value: resp.candidateContactChannels[0].value },
          { type: 2, value: resp.candidateContactChannels[1].value }
        ],
      };
    })
  );
}

因此,您无需订阅服务中的可观察对象,而是让服务器的响应“流”通过管道,并将“流”的所有内容映射到另一个对象,您可以在控制器中订阅该对象。 / p>

在这种情况下,尽管我看到您将从API获得的响应映射到完全相同的对象,这意味着您实际上可以执行以下操作:

service.ts

getUserDetails(): Observable<GetUserByIdModel> {
  const token = this._storeService.getStoredData().id_token;
  const candidateId = this._storeService.getStoredData().profile.CandidateId;
  const headers = new HttpHeaders()
    .set('Authorization', `Bearer ${token}`)
    .set('Content-Type', 'application/json');
  const options = { headers: headers };
  const url = `${this.candidateUrl}/Get/${candidateId}`;

  return this._http.get<GetUserByIdModel>(url, options);
}

您的component.ts类可以保持不变。