Subskrybowanie danych z API - czy to konieczne?

0

Witam.
Domyślam się, że wiąże się to z asynchronicznością, ale przetrzepałem parę forów i google i jakoś jednoznacznej odpowiedzi nie potrafię znaleźć.

Mam serwis

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class APIService {

  _baseUrl = 'http://192.168.0.108:9990/';

  constructor(private _http: HttpClient) { }

  public UserAuthentication2(email: string, password: string) {
    return this._http.post(this._baseUrl + 'api/v1.0/auth/userauthentication', { email: email, password: password, companyId: 0 });
  }
}

API w tym "zapytaniu" zwraca dane użytkownika wraz z jego konfiguracją. Mam model, ale nie będę go tutaj wrzucał w całości bo jest spory.

export class AuthenticationResponse {
  config: Config;
  user: User;
  token: string;
  company: Company;
}

export class User {
  id: number;
  name: string;
  firstname: string;
  lastname: string;
  email: string;
  password: string;
  roleID: number;
  avatar: string;
  isActive: boolean;
}
//...

Czy .subscribe() powinno być po stronie serwisu? Mam wrażenie, że subskrybowanie po stronie komponentu robi bałagan w kodzie, a asynchroniczność kompletnie nie pomaga, ponieważ jeden .subscribe() się jeszcze nie wykona do końca, a leci do następnego. Czasem subskrybowane dane są wymagane, aby zasubskrybować następne i tutaj też nie wiem co mam zrobić. W poprzednich swoich projektach mam taki bałagan z tego powodu, że teraz chciałbym to zrobić dobrze.

0

odniose sie jakby to byl TypeScript

wiec z APIService zwracalbym promise bo spodziewamy sie konkretnej jednej danej a nie strumienia danych (wiec nie obserable)
Component IMO powinien sam zajac sie subscribe. To Komponent wie w jakiej kolejnosci co potrzebuje a nie serwis.

0

Ok, a mógłbyś na moim przykładzie pokazać jak taki promise obsłużyć/przygotować?
Dlaczego zmieniając funkcje na

  public async UserAuthentication(email: string, password: string) {
    return await this._http.post<AuthenticationResponse>(this._baseUrl + 'api/v1.0/auth/userauthentication',
    { email: email, password: password, companyId: 0 });
  }

Pokazuje mi, że zwracaPromise<Observable<AuthenticationResponse>>, czy to nie wychodzi na jedno?

0

u Ciebie nie trzeba zmieniac, bo httpclient z tego co pamietam zawsze zwraca Promise.

Zobacz w dokumentacji co zwraca http client

0
    this.nextCacheOn$ = combineLatest(this.tenantId$).pipe(
      untilComponentDestroyed(this),
      switchMap(([tenantId]) => this.dashboardDataService.getNextCache(tenantId, this.chartId))
    )

    let refreshDiagrams = combineLatest(this.nextCacheOn$).pipe(
      untilComponentDestroyed(this),
      switchMap(([nextCacheOn]) => {
        var now = new Date();
        var nextCacheOnDate = new Date(nextCacheOn);
        if (nextCacheOnDate.valueOf() > now.valueOf())
        {
          var period = nextCacheOnDate.valueOf() - now.valueOf();
          if (period < 0) {
            period = period * -1;
          }

          return interval(period)
        }
        else
        {
          // otherwise refresh graph every 15 minutes
          return interval(900000)
        }
      })
    ) 

np mam taki kod w componencie i imo jest ok

4

Jeszcze nie spotkałem się z tym aby po stronie serwisu robić subscribe(). Jedynie można użyć pipe i operatorów typu map() filter() aby częściowo
przygotować / przetworzyć dane z response. Zwykle subskrybujesz po stronie komponentu, tam też obsługujesz ewentualne błędy i w razie ich wystąpienia
powiadamiasz użytkownika o niepowodzeniu. Możesz popatrzeć tutaj jak realizowałem security w angular https://github.com/lukascode/puns/tree/master/puns-web-client/src/app/security.

0

@fasadin: Nie wiem czy się mam sugerować tym co pokazuje mi VS Code, ale gdy mam taką funkcje pokazuje mi, że zwraca Observable<AuthenticationResponse>:

  public UserAuthentication(email: string, password: string) {
    return this._http.post<AuthenticationResponse>(this._baseUrl + 'api/v1.0/auth/userauthentication',
    { email: email, password: password, companyId: 0 });
  }

Jeżeli dodam async i await to wtedy pokazuje Promise<Observable<AuthenticationResponse>>. Czy powinienem zwrócić Promise<AuthenticationResponse>?

0

A czemu tak zależy Ci aby to przekształcić w Promise?

0

Bo tak @fasadin napisał, że by zwracał, więc ja też tak chce :D

wiec z APIService zwracalbym promise bo spodziewamy sie konkretnej jednej danej a nie strumienia danych (wiec nie obserable)

0
AdamWox napisał(a):

Bo tak @fasadin napisał, że by zwracał, więc ja też tak chce :D

wiec z APIService zwracalbym promise bo spodziewamy sie konkretnej jednej danej a nie strumienia danych (wiec nie obserable)

Możesz na Observable wywołać metodę toPromise() aby zamienić na promise. Preferuję Observable.

0

@lookacode1 czemu obserable?

Masz streamowanie tam?

Niestety nie mam dosc duzo czasu by odpowiedziec. Mam nadzieje ze niezapomne i odpowiem odpowiednio :)

0

Ktoś powiedział że Observable nie może wyemitować tylko jednej wartości?

1 użytkowników online, w tym zalogowanych: 0, gości: 1