Как получить данные из сервиса в ngOnInit Angular - PullRequest
0 голосов
/ 16 октября 2019

У меня проблема при попытке получить данные в ngOnInit из службы http. Мне нужно установить мои данные в переменную при запуске компонента, чтобы я мог использовать ее в других функциях.

Я добился этого, выполнив async ngOnInit и получив ответ от функции Promise, ноЯ не думаю, что это хорошая практика? Как я могу улучшить его?

Вот мой код:

COMPONENT.TS



     async ngOnInit() {
        this.username = localStorage.getItem('username');
        this.segment.value = 'FUNCIONAL';
        this.categoria = this.segment.value;
        this.listadoClases = await this.claseServicio.obtenerListadoClases(this.categoria); // **Need to set this variable at onInit**


SERVICE.TS


    getClases(actividad) {
        return this.http.get(`https://anders-test.herokuapp.com/clases/obtenerPorCategoria/${actividad}`);
      }


      obtenerListadoClases(categoria) {
        return new Promise(resolve => {
          this.getClases(categoria).subscribe(data => {
            if (data) {
              resolve(data)
            }
          })
        })
      }

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

Заранее спасибо, ребята!

Ответы [ 3 ]

1 голос
/ 16 октября 2019

Nyco, с какой стати вы все усложняете?

Сервис

  getClases(actividad) {
        return this.http.get(`https://anders-test.herokuapp.com/clases/obtenerPorCategoria/${actividad}`);
      }

Компонент

//inject the service in constructor
constructor(private service:Service){}

ngOnInit() {
    this.username = localStorage.getItem('username');
    this.segment.value = 'FUNCIONAL';
    this.categoria = this.segment.value;
    this.service.getClases(this.categoria).subscribe(res=>{
        this.categorias=res
    })
}

Вам следует избегать подписки на сервисыза исключением некоторых специальных функций. Подумайте, что Angular делает над Observables. Если вам нужно конвертировать Observable в Promise, это должно быть веским основанием для этого

0 голосов
/ 16 октября 2019

Чтобы получить данные и сохранить их в переменной, самое чистое решение, о котором я мог подумать, - запустить http-запрос OnInit метод жизненного цикла и сохранить его в Observable .

Например:

constructor(private http: HttpClient) {}

ngOnInit() {
    this.response$ = this.http.get('http://...');
}

Позже вы можете превратить response$ в обещание с помощью метода toPromise и использовать с ним async / await.
Кроме того, будьте осторожны, если вы используете response$ несколько раз, потому что это вызовет несколько HTTP-запросов, вы можете использовать оператор shareReplay , например:

ngOnInit() {
    this.response$ = this.http.get('http://...').pipe(shareReplay(1));
}
0 голосов
/ 16 октября 2019

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

Но если вы хотите подождать, пока данные будут извлечены из API, вы можете использовать Promise, и это можно обработать по ключевому слову , а затем . В современном Javascript вы можете справиться с этим, используя async / await . Что больше похоже на синхронный код и легко читается и понимается.

Пожалуйста, следуйте этому

 ngOnInit() {
    this.username = localStorage.getItem('username');
    this.segment.value = 'FUNCIONAL';
    this.categoria = this.segment.value;
    this.obtenerListadoClases(); 

Не рекомендуется добавлять асинхронный код перед ngOnInit

 async obtenerListadoClases() {
    try {
           this.listadoClases = await this.claseServicio.obtenerListadoClases(this.categoria);
        }).catch((e) => {
           console.log(e);
        });
  }

Поскольку HttpClient возвращает объект Observable в угловых 5 *, в этом случае вам нужно сделать метод асинхронным, который будет возвращать обещание. То, что вы можете сделать, как вы сделали.

return new Promise((resolve, reject) => {
      this.getClases(categoria).subscribe((res: any) => {
                resolve({status: 200, data: res});
            }, (error) => {
                resolve({status: 400, data:[]});
            },
            () => {
                resolve({status: 201, data:[]});
            });
    })

Для получения дополнительной информации, пожалуйста, проверьте это Использование функции асинхронного ожидания в Angular

...