如何从httpModule.get获取JSON响应?

时间:2019-07-02 12:53:19

标签: angular rxjs

我不知道如何从HttpModule的get()函数中获取JSON字符串。我将此API端点用作目标:https://reqres.in/api/users?page=1

如您所见,此端点返回JSON字符串。我不知道如何在我的Angular代码中获取此JSON字符串。我不断收到类似Observable或其他垃圾的信息。

export class LicenseService {

  users: any;

  constructor(private http: HttpClient) { }

  public getUsers(): void {
    const data = this.http.get('https://reqres.in/api/users?page=1').subscribe(res => this.users = JSON.stringify(res));
    console.log(this.users);
  }
}

我也尝试过这种方法,但这不起作用。

public getUsers(): void {
    const data = this.http.get('https://reqres.in/api/users?page=1');

    data.subscribe({
      next(response) {
        this.users = response;
        },
      error(err) { console.error('Error: ' + err); },
      complete() { console.log('Completed'); }
    });

    console.log(this.users);
  }

我以为我应该使用.subscribe来做到这一点,但是每次尝试在subscribe中使用下一个函数时,我都无法获得想要的东西。

我要做的就是能够访问端点返回的JSON,我该怎么做。

5 个答案:

答案 0 :(得分:3)

我已经回答了另一个问题,但这是使用rxjs的更好方法,因为应该使用它。

服务:license.service.ts

export class LicenseService {

  constructor(private http: HttpClient) { }

  getUsers() {
    return this.http.get('https://reqres.in/api/users?page=1').pipe(map(res=> res.data));
  }
}

组件:license.component.ts

@Component({
  selector: 'app-license',
  templateUrl: './license.component.html',
})
export class LicenseComponent {

  constructor(private licenseService: LicenseService) { }
  users$ = this.licenseService.getUsers();

}

模板:license.component.html

<div *ngFor="let user of users$ | async">
  {{user.first_name}} {{user.last_name}}
</div>

答案 1 :(得分:1)

第二种方法很接近。

此代码不起作用,因为您将异步与同步混合在一起。 console.log(this.users)在对后端的调用完成之前被执行。

尝试一下:

public getUsers(): void {
    this.http.get('https://reqres.in/api/users?page=1').subscribe(res => {
        this.users = res;
        console.log(res);
    });
}

[编辑]:

如果要返回数据,则必须执行其他建议的操作-将其转换为异步功能。

但是在这里,您可能不应该这样做。 RxJS的作用是,一旦您转到Rx,就应该保留Rx。您应该尝试使用observable.pipe()和各种操作符(如map()filter()every()count()等)来处理可观察对象(更多内容请参见文档-here

在处理这些可观察对象的各种方法的链结束时,您应该只调用subscribe。这样,您几乎可以像使用同步代码一样使用可观察对象,而不必担心问题中出现的类似情况。

答案 2 :(得分:0)

您可以做的是使用async函数和toPromise方法将可观察对象转换为Promise。

export class LicenseService {

  users: any;

  constructor(private http: HttpClient) { }

  async getUsers() {
    this.users = await this.http.get('https://reqres.in/api/users?page=1').toPromise();
    console.log(this.users);
  }
}

答案 3 :(得分:0)

您显然很不了解异步方法如何与其余同步代码交互。我将为您分解您的第一个代码。

//call the http service and use it to perform an HTTP GET.
//This is an asynchrounous call, meaning it out does not lock the rest of the application.
//The HTTP GET call starts, then the rest of your code runs.
const data = this.http.get('https://reqres.in/api/users?page=1')

//At this point, the HTTP GET has started, but since it is async, we do not wait for it to finish.
//So we log users. Users is CURRENTLY undefined (since our call hasn't finished yet.
console.log(this.users);

//After some (indeterminate) quantity of time, our HTTP GET finishes it's call.
//Now that it has finished its call, we perform the callback within the subscription.
//The subscription is an observable because it emits an event when it is finished.
//In our callback, we set the value of users.
.subscribe(res => this.users = JSON.stringify(res));

正如其他人所提到的,有几种解决问题的方法。您可以使用async / await(这是ES8功能)来延迟用户的控制台日志,直到HTTP GET完成调用为止。这与@Mateusz提供的代码相同。这不是处理情况的正确方法,并不是,但是async / await是您应该了解的JS功能。

async getUsers() {
   this.users = await this.http.get('https://reqres.in/api/users?page=1').toPromise();
   console.log(this.users);
}

或者,您可以在可观察对象的回调中重构代码以利用用户数据。这可能是处理这种情况的更好方法。您将需要重新设计代码,以便它可以处理来自服务器的异步调用结果。只需将日志放入回调即可解决当前的问题,但您需要考虑其他情况,尤其是如何使用用户数据。

this.http.get('https://reqres.in/api/users?page=1').subscribe(res => {
   this.users = JSON.stringify(res);
   console.log(this.users);
});

答案 4 :(得分:0)

我认为您需要将数据从 LicenseService 获取到组件。虽然 toPromise()是一个选项。您还可以使用 map 运算符。 我创建了一个例子。这是链接

https://stackblitz.com/edit/angular-api-call