1

I've been trying to solve the problem in different ways for a while now but nothing works. When I try to add the source of an image from the *ngFor loop from the unsplash link I get the following error: img source not found

I tried the following:

<img class="slide__image" [src]="slide.urls?.regular">
<img class="slide__image" src="{{slide.urls?.regular}}">

But it doesn't work either. In other ways I get unknown source or locahost error 404.

Here is the full code:

import { Component, OnInit, Input } from '@angular/core';
import { Subscription } from 'rxjs';
import { SharedService } from '../shared/shared.service';

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

export class SliderComponent implements OnInit {
      
      subscriptions: Subscription[] = [];

      currentSlide = 2;
      sliders: any = [];

      constructor(public sharedService: SharedService) { }

      ngOnInit() {

        this.subscriptions.push(
          this.sharedService.showSliders.subscribe((res) =>{
            console.log('first res', res);
            if(res){
              this.sliders.push(...res);
            }else{
              console.log('something went wrong .....');
              
            }
          })
        )

      }


      onSlideClick(index: number) {
        if (this.currentSlide !== index) {
          this.currentSlide = index;

              // document.getElementById('carousel').insertBefore(document.getElementById('carousel').children[4], document.getElementById('carousel').children[0])
              // // add click events to control arrows
              // document.getElementById('prev').addEventListener('click', prev, true);
              // document.getElementById('next').addEventListener('click', next, true);
          };
        }
      

      onPreviousClick() {
        const previous = this.currentSlide - 1
        this.currentSlide = previous < 0 ? this.sliders.length - 1 : previous;
        console.log('previous clicked, new current slide is: ', this.currentSlide);
        if(this.currentSlide === 0){

        }
      }

      onNextClick() {
        const next = this.currentSlide + 1
        this.currentSlide = next === this.sliders.length ? 0 : next;
        console.log('next clicked, new current slide is: ', this.currentSlide, "data :", this.sliders);
        if(this.currentSlide === 4){
          
        }
      }
      
      ngOnDestroy() {
        console.log("component is being destroyed")
        if(this.subscriptions.length > 0){
            this.subscriptions.forEach( (sub) => {
                console.log("subscription removed");
                sub.unsubscribe();
            })
            this.subscriptions = [];
        }
    }

}

    <div class="slider" *ngIf="sliders">
        <ul class="slider__wrapper" [style.transform] = "'translateX(-' + currentSlide * (100 / sliders.length) + '%)'">
        <!-- <ul class="slider__wrapper"> -->
            <li *ngFor="let slide of sliders; let i=index"
            class="slide" 
            #slide
            [class.slide--current]="slide.index === currentSlide" 
            [class.slide--next]="slide.index === currentSlide + 1"
            [class.slide--previous]="slide.index === currentSlide - 1"
            (click)="onSlideClick(slide.index)">
                <div class="slide__image-wrapper">
            <!-- <img class="slide__image" [src]="slide.urls?.regular"> -->
            <!-- <img class="slide__image" src="https://picsum.photos/800/300?image{{i}}" alt="{{slide?.alt_description}}"> -->
                    <img class="slide__image" src="{{slide.urls?.regular}}">
            <div id="blur">
            </div>
              <p class="index-img" >{{slide[i]}}</p>
              <!-- <p class="index-img" >{{[i]}}</p> -->
          </div>
          <p class="description-img">{{slide.alt_description}}</p>
        </li>
      </ul>

      <div class="slider__controls">
        <button class="btn btn--previous" title="Go to previous slide" (click)="onPreviousClick()">
          <svg class="icon" viewBox="0 0 24 24">
            <path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"></path>
          </svg>
        </button>
        <button class="btn btn--next" title="Go to next slide"  (click)="onNextClick()">
          <svg class="icon" viewBox="0 0 24 24">
            <path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"></path>
          </svg>
        </button>
      </div>
    </div>

And here is the object (I use unsplash) :

{
"id": "y2lCFKGZEXI",
"created_at": "2021-04-25T10:00:26-04:00",
"updated_at": "2021-04-26T15:54:01-04:00",
"promoted_at": "2021-04-26T15:54:01-04:00",
"width": 4000,
"height": 6000,
"color": "#a673a6",
"blur_hash": "LED96:z=0wx]9?nhxHRO.AV@V@t8",
"description": null,
"alt_description": "pink and white smoke illustration",
"urls": {
    "raw": "https://images.unsplash.com/photo-1619359209643-20df6a2465ad?ixid=MnwyMjU3NTZ8MHwxfGFsbHwzfHx8fHx8Mnx8MTYxOTQ2OTY1MA&ixlib=rb-1.2.1",
    "full": "https://images.unsplash.com/photo-1619359209643-20df6a2465ad?crop=entropy&cs=srgb&fm=jpg&ixid=MnwyMjU3NTZ8MHwxfGFsbHwzfHx8fHx8Mnx8MTYxOTQ2OTY1MA&ixlib=rb-1.2.1&q=85",
    "regular": "https://images.unsplash.com/photo-1619359209643-20df6a2465ad?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwyMjU3NTZ8MHwxfGFsbHwzfHx8fHx8Mnx8MTYxOTQ2OTY1MA&ixlib=rb-1.2.1&q=80&w=1080",
    "small": "https://images.unsplash.com/photo-1619359209643-20df6a2465ad?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwyMjU3NTZ8MHwxfGFsbHwzfHx8fHx8Mnx8MTYxOTQ2OTY1MA&ixlib=rb-1.2.1&q=80&w=400",
    "thumb": "https://images.unsplash.com/photo-1619359209643-20df6a2465ad?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=MnwyMjU3NTZ8MHwxfGFsbHwzfHx8fHx8Mnx8MTYxOTQ2OTY1MA&ixlib=rb-1.2.1&q=80&w=200"
},
"links": {
    "self": "https://api.unsplash.com/photos/y2lCFKGZEXI",
    "html": "https://unsplash.com/photos/y2lCFKGZEXI",
    "download": "https://unsplash.com/photos/y2lCFKGZEXI/download",
    "download_location": "https://api.unsplash.com/photos/y2lCFKGZEXI/download?ixid=MnwyMjU3NTZ8MHwxfGFsbHwzfHx8fHx8Mnx8MTYxOTQ2OTY1MA"
},
"categories": [],
"likes": 49,
"liked_by_user": false,
"current_user_collections": [],
"sponsorship": null,
"user": {
    "id": "ogQykx6hk_c",
    "updated_at": "2021-04-26T16:40:36-04:00",
    "username": "pawel_czerwinski",
    "name": "Paweł Czerwiński",
    "first_name": "Paweł",
    "last_name": "Czerwiński",
    "twitter_username": null,
    "portfolio_url": "http://paypal.me/pmcze",
    "bio": "If you'd like to support me, you can consider a donation ❤ In case you have any questions about how you can use the photos, please read https://help.unsplash.com/en/collections/1463188-unsplash-license 👍 ||| www.instagram.com/pmcze",
    "location": "Poland",
    "links": {
        "self": "https://api.unsplash.com/users/pawel_czerwinski",
        "html": "https://unsplash.com/@pawel_czerwinski",
        "photos": "https://api.unsplash.com/users/pawel_czerwinski/photos",
        "likes": "https://api.unsplash.com/users/pawel_czerwinski/likes",
        "portfolio": "https://api.unsplash.com/users/pawel_czerwinski/portfolio",
        "following": "https://api.unsplash.com/users/pawel_czerwinski/following",
        "followers": "https://api.unsplash.com/users/pawel_czerwinski/followers"
    },
    "profile_image": {
        "small": "https://images.unsplash.com/profile-1592328433409-d9ce8a5333eaimage?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=32&w=32",
        "medium": "https://images.unsplash.com/profile-1592328433409-d9ce8a5333eaimage?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=64&w=64",
        "large": "https://images.unsplash.com/profile-1592328433409-d9ce8a5333eaimage?ixlib=rb-1.2.1&q=80&fm=jpg&crop=faces&cs=tinysrgb&fit=crop&h=128&w=128"
    },
    "instagram_username": "pmcze",
    "total_collections": 20,
    "total_likes": 29503,
    "total_photos": 1070,
    "accepted_tos": true,
    "for_hire": false
}

}

Any ideas please?

1 Answer 1

1

By optional chaining, you could be passing undefined to the src attribute until it gets defined... try this instead:

<div *ngIf="slide.urls" class="slide__image-wrapper">
  <img class="slide__image" [src]="slide.urls.regular">
</div>

By using *ngIf="slide.urls" on the wrapping div, it ensures there is a urls object before trying to render the <img>.

Sign up to request clarification or add additional context in comments.

6 Comments

It don't show anything, the page is blank but I can see the 10 elements in the inspector but they are empty
make sure you have your data mapped properly, you can add `{{ slide.urls | json }} as a sibling of the slide image wrapper to debug
The data came from an api, they are already mapped So it didn't change anything
The purpose of inserting {{ slide.urls | json }} in your template is so you can VERIFY that the data is getting into your template. If the <img> is getting a url for its src attribute, it should work. If it's not working, that implies you did not wire up the data properly.
you did not understand. you put {{ slide.urls | json }} right next to the <div>. See what it outputs. Make sure there is data. If there is nothing, you did not wire it up correctly.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.