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

Pobranie zdjęcia z api - funkcja w angularze do obsługi wyświetlenia zdjęcia.

Object Storage Arubacloud
0 głosów
429 wizyt
pytanie zadane 19 lutego 2022 w JavaScript przez rszczepanski02 Obywatel (1,180 p.)

Cześć. Stworzyłem API, które pobiera zdjęcie użytkownika i specjalna funkcja w angularze je wyświetla. Pobrane zdjęcie jest typu blob. Ogólnie wszystko działa, jednak funkcję odpowiedzialną za wyświetlenie tego zdjęcia, chciałbym umieścić w osobnym pliku, tak abym w każdym z komponentów mógł z niej skorzystać i zwrócić z niej już gotowe zdjęcie do wyświetlenia (funkcja jest wykorzystywana w wielu miejscach i wielokrotne powielanie tego samego kodu trochę mnie męczy :D).

Funkcja:
 

  createImage(image: Blob) {
    if (image && image.size > 0) {
      const reader = new FileReader();

      reader.addEventListener("load", () => {
        this.profileImg = reader.result;
      }, false);
      reader.readAsDataURL(image);
    } else {
      this.profileImg = '../../../../assets/images/default_profile.png';
    }
  }

Czy ktoś ma może pomysł, jak to można fajnie zrobić? Ogólnie wyświetlanie zdjęć z api jest dla mnie nowością i ciężko mi znaleźć coś na ten temat w internecie.

Pozdrawiam i z góry dziękuję za pomoc!

1 odpowiedź

+2 głosów
odpowiedź 19 lutego 2022 przez ScriptyChris Mędrzec (190,190 p.)
wybrane 19 lutego 2022 przez rszczepanski02
 
Najlepsza

Myślę, że potrzebujesz tutaj użyć serwisu - umieść w nim funkcję createImage i możesz do niej przekazywać blob obrazka (obecnie argument image) oraz ścieżkę, którą teraz przypisujesz do this.profileImg w razie, gdy obrazka nie ma (niespełniony warunek image && image.size > 0). Możesz całość owinąć w promise i resolwować z niego zmienną zamiast obecnego użycia pola this.profileImg.

Przykład "na sucho":

export class ImageService {
  createImage(image: Blob, imagePath) {
    return new Promise((resolve) => {
      if (image && image.size > 0) {
        const reader = new FileReader();
 
        reader.addEventListener("load", () => {
          resolve(reader.result); // "zwróć" obrazek z promisa
        }, false);
        reader.readAsDataURL(image);
      } else {
        resolve(imagePath); // "zwróć" ścieżkę z promisa
      }
    });
  }
}

// użycie po wcześniejszym wstrzyknięciu serwisu do komponentu
this.imageService
  .createImage(image, '../../../../assets/images/default_profile.png')
  .then(imageResult => { /* tutaj będzie albo wczytany obrazek albo ścieżka */ })

 

komentarz 19 lutego 2022 przez rszczepanski02 Obywatel (1,180 p.)

Bardzo dziękuje.
Nie chciałbym nadużywać twojej pomocy, ale może wiesz z czego wynika błąd, który polega na tym, że zdjęcie pobierane i wyświetlane jest dopiero po odświeżeniu strony. W toolbar zdj profilowe jest zdefiniowane w taki sam sposób jak na podstronie angularowej. W toolbarze wszystko działa, po zalogowaniu normalnie ustawia się profilowe, a w przypadku podstrony (pomimo użycia tej samej metody), zdjęcie się nie wyświetla. Ani domyślne, ani to z backendu. Pojawia się dopiero po odświeżeniu strony :/

Serwis:

  getUserProfileImg(): Observable<Blob | null> {
    return this.userProfileImage;
  }

  setUserProfileImage(): void  {
    this.http.get(`${this.api}/employee_profile_img`, { responseType: 'blob' }).subscribe(
      response => {
        this.userProfileImage.next(response);
      }
    )
  }

 

Podstrona:

  ngOnInit(): void {
    this.profileImgSubscription = this.employeeService.getUserProfileImg().subscribe(response => {
      if(response) {
        this.imageConventerService.createImage(response, '../../../../assets/images/default_profile.png')
          .then(img => this.profileImg = img);
      }
      this.profileImg = '../../../../assets/images/default_profile.png';
    });
  }


HTML:

<img [src]="profileImg" *ngIf="profileImg" width="46px" height="46px" class="profile_img mat-elevation-z10" alt="" />


Może coś poradzisz! Jeszcze raz dziękuje za pomoc.

komentarz 19 lutego 2022 przez ScriptyChris Mędrzec (190,190 p.)

Pewności nie mam (przydało by się móc przetestować kod), ale wydaje mi się, że gdy pobierzesz obrazek nie będąc jeszcze na tej docelowej podstronie, to rozwiązujesz promisa ("wyczerpując" tym samym subskrypcję) z metody setUserProfileImage i wtedy this.uesrProfileImage już nie propaguje danych obrazka, gdy w ngOnInit podpina się do niego subskrypcja. Gdy odświeżasz docelową podstronę, to możliwe że obrazek pobiera się dlatego, bo promis nie został jeszcze przez nic rozwiązany, więc propaguje dane do subskrypcji.

Możesz zweryfikować czy problem występuje w drugą stronę: odśwież podstronę i wróć na toolbar - jeśli sposób ładowania obrazka jest identyczny w obu przypadkach, to tym razem na toolbarze obrazek nie powinien się załadować.

Ani domyślne, ani to z backendu.

Co masz na myśli przez "domyślne", a co przez "z backendu"?

komentarz 19 lutego 2022 przez rszczepanski02 Obywatel (1,180 p.)

Domyślne zdjęcie dla osób, które nie posiadają zarejestrowanego zdjęcia na backend. Toolbar jest wyświetlany cały czas jeśli użytkownik jest zalogowany.
 

Zdjęcie w toolbar jest elegancko załadowywane po zalogowaniu i zapisywane w zmiennej w serwisie. Przejście na stronę settings powoduje pobranie tej zmiennej przechowywanej w serwisie, która jest typu Blob i w teorii wyświetlenie jej.

komentarz 19 lutego 2022 przez ScriptyChris Mędrzec (190,190 p.)

A jeśli się zalogujesz, pójdziesz do podstrony (na której teraz zdjęcie się nie ładuje), odświeżysz stronę (zdjęcie się załaduje) i wrócisz na toolbar - czy zdjęcie się załaduje?

Toolbar jest wyświetlany cały czas jeśli użytkownik jest zalogowany.

Czy to znaczy, że toolbar jest cały czas aktywny w tle, więc gdy odświeżysz podstronę, to zdjęcie załaduje się w obu miejscach?

komentarz 19 lutego 2022 przez rszczepanski02 Obywatel (1,180 p.)
Tak gdy odświeżę stronę to zdjęcie załaduje się ponownie w obudwu miejscach, jednak za pierwszym razem na podstronie nie chcę się załadować, z toolbarem nie ma problemu. Jeśli zmienię podstronę to zdjęcie i tak się nie załaduje.
komentarz 19 lutego 2022 przez ScriptyChris Mędrzec (190,190 p.)
A jeśli usuniesz/zakomentujesz kod toolbara, który pobiera zdjęcie, to czy ono się załaduje na podstronie (nawet po jej odświeżeniu)? Pytam, bo może toolbar jest tym faktycznym inicjatorem pobierania zdjęcia, a samo to, że po odświeżeniu podstrony obrazek ładuje się również tam, jest jakimś efektem ubocznym?
komentarz 20 lutego 2022 przez rszczepanski02 Obywatel (1,180 p.)
Nie wiem czy dobrze się zrozumieliśmy :D Trochę poplątałem. Spróbuje to sam rozwiązać. Dzięki za poświęcony czas i pomoc!

Podobne pytania

0 głosów
1 odpowiedź 236 wizyt
pytanie zadane 28 października 2020 w JavaScript przez Krzysztof92 Początkujący (290 p.)
0 głosów
1 odpowiedź 113 wizyt
pytanie zadane 21 kwietnia 2019 w C i C++ przez Akiro Bywalec (2,910 p.)
0 głosów
0 odpowiedzi 238 wizyt

92,536 zapytań

141,376 odpowiedzi

319,451 komentarzy

61,920 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

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy 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!

...