• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Angular 2 - mała pomoc w zrozumieniu.

VPS Starter Arubacloud
0 głosów
443 wizyt
pytanie zadane 31 stycznia 2018 w JavaScript przez No Lime Gaduła (4,540 p.)
Witajcie po ogromnej przerwie.

Zakupiłem sobie książkę (niedawno wydana) dotyczącą Angualar 2 a konkretnie "Angular 2 - Programowanie z użyciem języka TypeScript" - Yakov Fain & Anton Moiseev.

Mam problem z ogarnięciem jednej rzeczy, nie mogę tego przeskoczyć od kilku dni.

Mam komponent który wykorzystuje DI i importuje mój serwis. Serwis zaś importuje protokół HTTP. W serwisie mam metodę która zwraca obiekt typu Observable (tam też konwertuje dane do json). W komponencie subskrybuje no i dane w widoku wyświetlam. Ok, wszystko super. Ale za każdym razem kiedy odpala się ten konkretny route z podczepionym w/w komponentem ten Request jest wykonywany jeszcze raz. A nie chcę tego gdyż wystarczy mi 100 takich requestów (a w tym przypadku są 4 requesty na start bo mam 4 userów dla których dane chcę pobrać ) i dostaję bana od aplikacji z której API to pobieram.

Chciałbym to zrobić tak na przykład, aby user na jedną swoją wizytę wysyłał tylko raz takie rządanie a później te dane byłyby przechowywane aż do opuszczenia przez niego strony. No nie wiem, pewnie jest jeszcze inne, bardziej optymalne rozwiązanie jak nie wyłapać blokady od serwisu za zbyt dużą ilość requestów.

Pomocy :)
komentarz 31 stycznia 2018 przez ScriptyChris Mędrzec (190,190 p.)

Pokaż kod.

Możesz przypisać do sessionStorage dane i sprawdzać przy każdej inicjalizacji komponentu, czy te dane już są dostępne, czy nie.

Nie pisałem w Angular 2+ już kilka miesięcy (zwłaszcza, że teraz jest wersja 5), ale jeśli dobrze kojarzę, to Observable pozwalało podpiąć się pod coś raz.

komentarz 4 lutego 2018 przez No Lime Gaduła (4,540 p.)

To mój plik summoner.ts: 

export interface Summoner {
     
                accountId: string,
                id: string,
                name: string,
                profileIconId: string,
                revisionDate: string,
                summonerLevel: string,
       
 
        
      
    }
To mój plik dataservice.ts:
@Injectable()
export class DataService {
  friends = FRIEND;
  apikey = APIKEY;
  nick: any[];
  query: string;

  public apiUrl =
    'https://eun1.api.riotgames.com/lol/summoner/v3/summoners/by-name/';
  data: Array<any> = [];
  constructor(private http: Http) { }
  getFriendData(query):Observable<Summoner>{

    return this.http.get(query)
      .map((res: Response) => res.json())
      .catch((error: any) => Observable.throw(error.json().error || 'Server error'));

  }

}

To mój Friend Component:

@Component({
  selector: 'app-friends',
  providers: [DataService],
  templateUrl: './friends.component.html',
  styleUrls: ['./friends.component.css']
})
export class FriendsComponent implements OnInit {
  data: any;
summoner: Summoner[] = [];

  constructor(public dataService:DataService) {
    

    
  }


fetchSummoner(){
  
  this.dataService.getFriendData(this.dataService.query).subscribe(
    data => {this.summoner.push(data);
      
      }

  )

}
  ngOnInit() {
if(this.summoner){
  return Observable.of(this.summoner);
} else {
  for (let i of this.dataService.friends) {
    this.dataService.query = `${this.dataService.apiUrl}${i.nick}${this.dataService.apikey}`;

    this.fetchSummoner();

  }
}
 

   
  }

}

I w dalszym ciągu spamuje zapytaniami. Przy każdym odwiedzeniu route, w zakładce Sieć widzę, że komponent wysyła te trzy zapytania do strony Riot.

2 odpowiedzi

0 głosów
odpowiedź 1 lutego 2018 przez zgrybus Pasjonat (24,860 p.)
wybrane 5 lutego 2018 przez No Lime
 
Najlepsza

przypisz wynik z pobrania do jakieś zmiennej w tym serwisie :)

np.

kodzik serwisu:

export class MyService{
   private dataFromDb: any[];
   
   getData(): Observable<any> {
      if(dataFromDb)
         return Observable.of(this.dataFromDb);
      return this.http.get()
                .map(res => res.json())
                .do(res => this.dataFromDb = res)
                .catch(err => Observable.throw(err.json() || 'Błąd');
   }
}

 

komentarz 4 lutego 2018 przez No Lime Gaduła (4,540 p.)

Batch call. Wytłuszczony tekst - info na temat usunięcia takiej możliwości

Wyżej daje Ci link. Niestety nie można tak robić. Nie rozumiem tej decyzji bo teraz muszę spamować im zapytaniami.

Nie mogę tak po prostu pushnąć tych danych do tej zmiennej. Wyskakuje error :

this.dataFromDb is undefined

a dataFromDb wygląda tak:

  private dataFromDb: any[];

wiem, że często rozwiązaniem był taki zapis:

  private dataFromDb: any[] = [];

ale gdy tak robię dostaje ciągle pusty Array.
Ręce mi opadają. Problem który powinien wymagać 5 minut, zajmuje mi obecnie już kilka dni... wstyd.

komentarz 5 lutego 2018 przez zgrybus Pasjonat (24,860 p.)
To pytanie, czy ZAWSZE będziesz pobierał tylko 3 summonerów?
Bardzo dziwne, że ich API nie pozwala na pobieranie większej ilości danych aniżeli jeden summoner.
komentarz 5 lutego 2018 przez No Lime Gaduła (4,540 p.)
Też się ździwiłem. Będę pobierać max 10 graczy. Minimum trzech graczy.
komentarz 5 lutego 2018 przez No Lime Gaduła (4,540 p.)

Jeden z użytkowników strony stackoverflow rozwiązał ten problem. Nie sądziłem, że to było tak proste chociaż nie wpadłbym na to za szybko.

dataFromDb:any={};
getData(query): Observable<any> {
if(this.dataFromDb[query])
{
  return Observable.of(this.dataFromDb[query]);
}

    return this.http.get(query)
      .map(res => res.json())
      .do(res => this.dataFromDb[query] = res)
      .catch(err => Observable.throw(err.json() || 'Błąd');
  }
}

 

I tak dam Ci najlepszą odpowiedź bo najbardziej się zaangażowałeś. Pozdrawiam.

komentarz 5 lutego 2018 przez zgrybus Pasjonat (24,860 p.)
ojeju.. w ogóle nie pomyślałem o tym sposobie..

eh, mogłoby być to rozwiązane 2 dni temu, ale cóż - zapomniało się.
0 głosów
odpowiedź 1 lutego 2018 przez maciej.tokarz Nałogowiec (27,280 p.)

A nie możesz w jednym żądaniu pobierać kilku informacji?

przykład

M.

komentarz 4 lutego 2018 przez No Lime Gaduła (4,540 p.)
Ciekawe podejście. Będę starał się przerobić mój kod na podobny do Twojego zaraz po tym jak uda mi się zrozumieć źródło mojego problemu. Kod wstawiłem wyżej. Dzięki za odpowiedź.

Podobne pytania

0 głosów
4 odpowiedzi 880 wizyt
pytanie zadane 13 sierpnia 2018 w JavaScript przez Tomek Reda Obywatel (1,110 p.)
0 głosów
2 odpowiedzi 305 wizyt
pytanie zadane 25 grudnia 2017 w JavaScript przez Sidzej Użytkownik (850 p.)
0 głosów
2 odpowiedzi 1,556 wizyt
pytanie zadane 2 marca 2017 w JavaScript przez JakubLabudda Użytkownik (640 p.)

92,455 zapytań

141,263 odpowiedzi

319,100 komentarzy

61,854 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...