• 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.

Aruba Cloud PRO i VPS, Openstack, VMWare, MS Hyper-V
0 głosów
134 wizyt
pytanie zadane 19 lutego w JavaScript przez rszczepanski02 Obywatel (1,090 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 przez ScriptyChris Mędrzec (187,840 p.)
wybrane 19 lutego 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 przez rszczepanski02 Obywatel (1,090 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 przez ScriptyChris Mędrzec (187,840 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 przez rszczepanski02 Obywatel (1,090 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 przez ScriptyChris Mędrzec (187,840 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 przez rszczepanski02 Obywatel (1,090 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 przez ScriptyChris Mędrzec (187,840 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 przez rszczepanski02 Obywatel (1,090 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ź 91 wizyt
pytanie zadane 28 października 2020 w JavaScript przez Krzysztof92 Początkujący (290 p.)
0 głosów
1 odpowiedź 95 wizyt
pytanie zadane 21 kwietnia 2019 w C i C++ przez Akiro Bywalec (2,910 p.)
0 głosów
0 odpowiedzi 154 wizyt

89,768 zapytań

138,375 odpowiedzi

309,458 komentarzy

59,679 pasjonatów

Advent of Code 2022

Top 15 użytkowników

  1. 1088p. - Argeento
  2. 1024p. - rucin93
  3. 1020p. - Michal Drewniak
  4. 1014p. - Łukasz Eckert
  5. 988p. - TheLukaszNs
  6. 963p. - JMazurkiewicz
  7. 960p. - adrian17
  8. 945p. - Jarosław Roszyk
  9. 920p. - Mawrok
  10. 914p. - overcq
  11. 900p. - nidomika
  12. 872p. - Mikbac
  13. 859p. - ssynowiec
  14. 848p. - Adam Salamon
  15. 811p. - Hubert Chęciński
Szczegóły i pełne wyniki

Motyw:

Akcja Pajacyk

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

Sklep oferujący ćwiczenia JavaScript, PHP, rozmowy rekrutacyjne dla programistów i inne materiały

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...