Как получить ответ JSON от httpModule.get? - PullRequest
1 голос
/ 02 июля 2019

Я не могу понять, как получить строку JSON из функции get() HttpModule. Я использую эту конечную точку API в качестве своей цели: https://reqres.in/api/users?page=1

Как видите, эта конечная точка возвращает строку JSON. Я не могу понять, как получить эту строку JSON в моем коде Angular. Я продолжаю получать такие вещи, как 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 для этого, но каждый раз, когда я пытаюсь использовать следующую функцию внутри подписки, я не получаю то, что хочу обратно.

Все, что я хочу сделать, - это иметь доступ к JSON, который возвращается конечной точкой, как мне это сделать.

Ответы [ 5 ]

3 голосов
/ 02 июля 2019

Я уже сделал другой ответ, но здесь лучше работает с использованием 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 голос
/ 02 июля 2019

Второй подход близок.

Этот код не работает, потому что вы смешиваете асинхронный с синхронным.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() и т. Д. (Больше можно найти в документации - здесь .

В конце цепочки различных методов, работающих с этими наблюдаемыми, вы должны сделать один вызов subscribe. Таким образом, вы будете работать с наблюдаемыми почти так же, как с синхронным кодом, и не будетенужно беспокоиться о таких вещах из вашего вопроса.

0 голосов
/ 02 июля 2019

Я думаю, вам нужно получить данные от LicenseService к компоненту. В то время как toPromise () является опцией. Вы также можете использовать оператор map . Я создал пример. Вот ссылка

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

0 голосов
/ 02 июля 2019

Вы совершенно не понимаете, как асинхронные методы взаимодействуют с остальной частью вашего синхронного кода.Я сломаю ваш первый код для вас.

//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);
});
0 голосов
/ 02 июля 2019

Что вы можете сделать, это использовать асинхронную функцию и метод toPromise, чтобы преобразовать наблюдаемое в обещание.

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);
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...