Как обрабатывать асин c HTTP-вызовы в Angular 8? - PullRequest
0 голосов
/ 10 апреля 2020

Итак, я новичок в Angular TypeScript и у меня возникла проблема.

Итак, у меня есть два файла: один - это файл компонента с функцией, которую я использую на экране, а второй - служба HTTP. файл, в котором я выполняю вызовы на сервер.

Текущая структура моего кода:

UserProfileComponent.ts

import { Component, OnInit } from '@angular/core';
import { UserService } from 'src/app/services/user.service';

@Component({
  selector: 'app-userprofile',
  templateUrl: './userprofile.component.html',
  styleUrls: ['./userprofile.component.scss']
})
export class UserprofileComponent implements OnInit {

  dataObj: any;

  constructor(private userService: UserService) {
    this.dataObj = this.userService.testCall();
    console.log('dataObj-> ' + JSON.stringify(this.dataObj));
  }

  ngOnInit() {
  }

}

и user .service.ts где у меня есть этот вызов

  testCall(): any{
    let responseObj: any;
    this.http.get(`${this.baseUrl}/users`).subscribe((data) => {
      console.log('responseObj-> '+JSON.stringify(data));
      responseObj = data;
    });
    return responseObj;
  }

Так что эта проблема для меня заключается в обработке асинхронного вызова c, console.log('dataObj-> ' + JSON.stringify(this.dataObj)) не ожидает завершения вызова службы и таким образом печатает undefined.

Я знаю, что это работает, но как мне обработать это программно?

Я хочу получить данные ответа, прежде чем перейти к следующей строке.

Angular CLI: 8.3.25, узел: 12.16.1, ОС: win32 x64, Angular: 8.2.14

Ответы [ 2 ]

2 голосов
/ 10 апреля 2020

Проблема в том, что вы делаете subscribe в своем сервисе, но вместо этого вы должны сделать это в своем компоненте и вернуть Observable из сервиса.

Таким образом, окончательный код должен выглядеть следующим образом:

testCall(): Observable<UserType[]> {
  //I suppose you return Array of Users
  return this.http.get(`${this.baseUrl}/users`);
}

и компонент

export class UserprofileComponent implements OnInit {
  dataObj: UserType[];

  constructor(private userService: UserService) {        
  }

  ngOnInit() {
    this.userService.testCall()
      .subscribe((response: UserType[]) => {
        dataObj = response;
        console.log('dataObj-> ' + JSON.stringify(this.dataObj));
      });
  }
}
1 голос
/ 10 апреля 2020

Как объяснил @Yury, вам нужно получить подписку на уровень компонента от уровня обслуживания.

Чтобы сделать его еще лучше, создайте службу API, как показано ниже:

api.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { map, catchError, timeout, retry } from 'rxjs/operators';
import { CookieService } from 'ngx-cookie';
import { SERVER } from './static/static.json';

@Injectable({
    providedIn: 'root'
})


export class ApiService {
    user: Observable<any>;
    headers: HttpHeaders;

    constructor(
        private http: HttpClient,
        private cookieService: CookieService
    ) { }
    get(url: string, options?: any) {
        let key = SERVER.api + url;
        this.headers = new HttpHeaders();
        if(typeof options == 'string' && options != " "){
            this.headers = new HttpHeaders().append('Authorization', options);
        }
        return this.http.get(key, {headers: this.headers, withCredentials: false})
        .pipe(
            timeout(15000),
            retry(5),
            catchError(err => throwError(err))
        )
    }
    post(url: string, data: any, options?: any) {
        let key = SERVER.api + url;
        this.headers= new HttpHeaders();

        if(typeof options == 'string' && options != " "){
            this.headers = new HttpHeaders().append('Authorization', options);
        }

        return this.http.post<any>(key , data, {headers: this.headers, withCredentials: false})
        .pipe(
            catchError(err => throwError(err))
        );
    }

    put(url: string, data: any, options?: any) {
        let key = SERVER.api + url;
        this.headers= new HttpHeaders();

        if(typeof options == 'string' && options != " "){
            this.headers = new HttpHeaders().append('Authorization', options);
        }

        return this.http.put<any>(key , data, {headers: this.headers, withCredentials: false})
        .pipe(
            catchError(err => throwError(err))
        );
    }

    delete(url: string, options?: any) {
        let key = SERVER.api + url;
        this.headers= new HttpHeaders();

        if(typeof options == 'string' && options != " "){
            this.headers = new HttpHeaders().append('Authorization', options);
        }

        return this.http.delete<any>(key, {headers: this.headers, withCredentials: false})
        .pipe(
            catchError(err => throwError(err))
        );
    }

}

Затем создайте службу уровня модуля,

abs.service.ts

import { Injectable } from '@angular/core';
import { ApiService } from './shared/api.service';
import { AuthService } from './shared/auth.service';
@Injectable({
    providedIn: 'root'
})
export class ABSService {

    constructor(
        private _API: ApiService,
        private _AUTH: AuthService
    ){}
    getUsers(option?) {
        let url = '/users';
        let token;
        if(option){
            url = url + "?" + option;
        }
        if(this._AUTH.loginCheck()){
            token = this._AUTH.getCookie();
        }
        return this._API.get(url, token);
    }

    postUsers(data) {
        let url = '/users';
        let token;
        if(this._AUTH.loginCheck()){
            token = this._AUTH.getCookie();
        }
        return this._API.post(url,data, token);
    }
}

Затем вы можете использовать эту службу уровня модуля в компоненте уровня модуля следующим образом:

abs.component.ts

import { Component, OnInit } from '@angular/core';
import { ABSService } from './abs.service';

@Component({
    selector: 'app-abs',
    templateUrl: './abs.component.html',
    styleUrls: ['./abs.component.css']
})

export class ABSComponent implements OnInit {
    constructor(
        private _API: ABSService
    ) {}
    ngOnInit(){
        this._API.getUsers().subscribe(
            (data:any)=>{
                // something related to data
                this.dataObj = data;
                console.log('dataObj-> ' + JSON.stringify(this.dataObj));
            },
            (err)=>{
                // something related to error
            }
        )
    }
}

Я предпочитаю держать модуль HTTP отдельно, так как в последний раз, когда они меняли модуль HTTP с помощью модуля HttpClient, мне пришлось go проделать большую работу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...