【问题标题】:undefined value after subscribing to endpoint订阅端点后未定义的值
【发布时间】:2019-10-25 20:21:57
【问题描述】:

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

这是我的代码

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 正确显示填充的数据

【问题讨论】:

  • 如果console.log(this)完成而不是console.log(this.user),你能告诉console中显示的内容吗?
  • 然后我得到MyDetailsComponent {_profileService: ProfileService, _confirmationService: ConfirmationService, _loader: LoaderService, _errorService: ErrorService, _storeService: StoreService, …} user: undefined

标签: angular


【解决方案1】:

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

在你的情况下,这意味着这样的事情:

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 }
        ],
      };
    })
  );
}

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

在这种情况下,尽管我看到您将从 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 类可以保持不变。

【讨论】:

    【解决方案2】:

    this.http.get() 是一个异步调用。在调用结束之前,您将返回 observable。

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

    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();
      })
    }
    

    【讨论】:

    • 我在服务中收到一个错误。声明类型既不是“void”也不是“any”的函数必须返回一个值。
    猜你喜欢
    • 2021-07-03
    • 1970-01-01
    • 2021-05-16
    • 2020-11-21
    • 1970-01-01
    • 2021-04-27
    • 2022-07-29
    • 1970-01-01
    • 2018-07-18
    相关资源
    最近更新 更多