【问题标题】:Http subscribe not working on Service Angular [duplicate]Http订阅不适用于Service Angular [重复]
【发布时间】:2022-01-05 09:01:48
【问题描述】:

我正在处理一个项目,我需要从自定义服务器检索数据。我为处理请求创建了一个 httpclient 服务,但遇到了这个问题:当我尝试订阅将数据传递给组件时,没有任何反应,但如果我在组件中进行订阅,evetything 工作正常。我重新假设下面的代码:

组件:

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { BehaviorSubject, catchError, map, Observable, of} from 'rxjs';
import { Food } from '../api/api-models';
import { ApiService } from '../api/api.service';

@Component({
  selector: 'app-in-home-list',
  templateUrl: './in-home-list.component.html',
  styleUrls: ['./in-home-list.component.css']
})
export class InHomeListComponent implements OnInit {

  res: Food[];
  error: string;

  constructor( private api: ApiService, private http: HttpClient){
  }

  ngOnInit() {
    //this.http.get<Food[]>('https://localhost:5001/').pipe(catchError(this.api.handleError)).subscribe({next: r => this.res = r, error: e => this.error = e});
    [this.res, this.error] = this.api.getInHomeList();
  }
}

注释的行是在这里工作的行,但不在服务中,未注释的行是我想要正常工作的行。

服务:

import { Injectable} from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Food } from './api-models';
import { catchError, throwError } from 'rxjs';

@Injectable({
  providedIn: 'root'
})

export class ApiService {

  private result: Food[];
  private error: string;

  constructor( private http: HttpClient) {

  }

  getInHomeList(): [Food[], string] {

    this.http.get<Food[]>('https://localhost:5001/').pipe(catchError(this.handleError)).subscribe({next: r => this.result = r, error: e => this.error = e});

    return [this.result, this.error];
  }

  handleError(error: any) {
    let errorMessage = "";
    if (error.error instanceof ErrorEvent) {
        // client-side error
        errorMessage = `Error: ${error.error.message}`;
    } else {
        // server-side error
        errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
    }
    console.log(errorMessage);
    return throwError(() => new Error(errorMessage))
  }
}

app.module.ts 中的@NgModule:

@NgModule({
  declarations: [
    AppComponent,
    InHomeListComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
  ],
  providers: [
    ApiService
  ],
  bootstrap: [AppComponent]
})

我对 Angular 有点陌生,所以也许我遗漏了一些东西,或者我不太了解 Observable 的真正工作原理。

【问题讨论】:

  • 是异步的,订阅回调在你返回之前不会被调用。
  • 您好,感谢您的回答。你能更好地解释我吗?我在 Angular 文档中表示,在执行 .subscribe() 方法时调用了对服务器的调用。那是对的吗?所以你的意思是返回发生在http请求结束之前?
  • 感谢您的分享,这让我更清楚了这一点。
  • 非常感谢!这可能会做的事情!

标签: angular typescript observable angular-services angular-httpclient


【解决方案1】:

上面注释的意思是“订阅”方法内部的内容是异步的,这意味着您的 getInHomeList() 方法不一定按写入的顺序运行。这意味着,您的“subscribe()”方法内部可能需要 5 秒(或多或少)才能得到响应,但您的“return”行将立即返回,没有数据。

拥有 http 数据服务的常见方式是这样的,将 objservable 本身返回给组件:

    public getInHomeList(): Observable<Food[]> {
        return this.http.get<Food[]>('https://localhost:5001/')
        .pipe(catchError(this.handleError));
      }

      handleError(error: any) {
        let errorMessage = "";
        if (error.error instanceof ErrorEvent) {
            // client-side error
            errorMessage = `Error: ${error.error.message}`;
        } else {
            // server-side error
            errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
        }
        console.log(errorMessage);
        return throwError(() => new Error(errorMessage))
      }

然后订阅 observable 并在您需要的任何组件中获取结果:

ngOnInit() {
    this.api.getInHomeList()
        .subscribe({next: r => this.res = r, error: e => this.error = e});
  }

“subscribe”方法内部是异步的,因此设置“R”的值可能需要更长的时间。但无论需要多长时间才能获得响应,ngOnInit() 方法的其余部分都将继续运行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-08
    • 1970-01-01
    • 2021-05-18
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多