简体   繁体   中英

how do i Delay a component html from loading till all images are gotten?

i have a home page where i want to display the first 3 images as a slider which are called from an API. this is my controller

export class ClientComponent implements OnInit {   public event;   public imgePAth: any;   public singleImg: any;   public secondImg: any;   public isAv: boolean = false;   filtersLoaded: Promise<boolean>;

  constructor(private servive: TycketService, private http: HttpClient,private route: Router) { }

  ngOnInit() {
    this.servive.allEvent().subscribe(data => {
      this.event = data;
      console.log(this.event);

      this.imgePAth = this.servive.imagebaseUrl(this.event[0]['image']);
      this.singleImg = this.servive.imagebaseUrl(this.event[1]['image']);
      this.secondImg = this.servive.imagebaseUrl(this.event[2]['image']);
      this.isAv = true;
      this.filtersLoaded = Promise.resolve(true);
      console.log(this.imgePAth);
    });   } }

my api service

  imagebaseUrl(data){
    return (this.imageUrl + data);
  }

my html ignore the event index, i am setting the background image w the [ngStyle], when i inspect i get an undefined path of the variable, but when i console.log the path in my ngOnInit i get the right path

<div class="cover_slider owl-carousel owl-theme" *ngIf="filtersLoaded | async">
        <div class="overlay">
            <div class="cover_item" [ngStyle]="{'background-image':'url('+imgePAth+')'}">
                <div class="slider_content">
                    <div class="slider-content-inner">
                        <div class="container">
                            <div class="slider-content-center" *ngIf="event && event[0]">
                                <h2 class="cover-title">
                                    Prepare yourself for
                                </h2>
                                <strong class="cover-xl-text">{{event[0]['name']}}</strong>
                                <p class="cover-date">
                                    {{event[0]['date']}}  - {{event[0]['venue']}} {{event[0]['location']}}.
                                </p>
                                <button class=" btn btn-primary btn-rounded" (click)="onClickBuy(event[0])">Buy Tickets Now</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
</div>

what is the solution for this? enter image description here

I suggest you use a tap pipe on your Observable

import { tap } from 'rxjs/operators';

 this.servive.allEvent().pipe(tap(_ => {
    // image loading code that you want to execute
   })).subscribe((val) => {
   console.log(val);
   });

EDIT

*ngIf="event && event[0]"

should be

*ngIf="event"

Do you only want to display this block of code if event array has something inside? Just having event will give you a truthy value if something is there. If there is nothing in your array, then event[0] could be undefined and throw an error.

I guess it was erased by DomSanitazer in order to prevent XSS attacks on your application. to turn it off you can

constructor(private sanitizer: DomSanitizer){}
.....
this.imgePAth = this.sanitizer.bypassSecurityTrustResourceUrl(someUrl)

it turned out that the pictures were coming down.

<div class="cover_slider owl-carousel owl-theme" *ngIf="filtersLoaded | async">
    <div class="overlay">
        <div class="cover_item" [ngStyle]="{'background-image':'url('+imgePAth+')'}">
            <div class="slider_content">
                <div class="slider-content-inner">
                    <div class="container">
                        <div class="slider-content-center" *ngIf="event && event[0]">
                            <h2 class="cover-title">
                                Prepare yourself for
                            </h2>
                            <strong class="cover-xl-text">{{event[0]['name']}}</strong>
                            <p class="cover-date">
                                {{event[0]['date']}}  - {{event[0]['venue']}} {{event[0]['location']}}.
                            </p>
                            <button class=" btn btn-primary btn-rounded" (click)="onClickBuy(event[0])">Buy Tickets Now</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

when i took out the ngIf condition, (*ngIf="event && event[0]") the pictures and details are rendered. i added that condition to resolve this error

ERROR MESSAGE

ClientComponent.html:58 ERROR TypeError: Cannot read property '0' of undefined
    at Object.eval [as updateRenderer] (ClientComponent.html:58)
    at Object.debugUpdateRenderer [as updateRenderer] (core.js:30069)
    at checkAndUpdateView (core.js:29444)
    at callViewAction (core.js:29680)
    at execComponentViewsAction (core.js:29622)
    at checkAndUpdateView (core.js:29445)
    at callViewAction (core.js:29680)
    at execEmbeddedViewsAction (core.js:29643)
    at checkAndUpdateView (core.js:29440)
    at callViewAction (core.js:29680)

making sure i had the events so i could access their indexs, although their details are rendered, the error comes up in the console how can i go about this?

well in recent time, the best to do is use resolvers when getting that route. read more about resolvers here resolvers , but an overview is: resolvers basically doesnt render the route till a specific data is fetched before letting the components load. an example is:
Resolver ts file:

@Injectable()
  export class MainStoreResolve implements Resolve<any> {
     constructor(private  storeService: StoreService){}
     resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): 
     Observable<any> {
        return this.storeService.mainStore(route.params.identifier);
   }
 }

App.routing.ts:

{
  path: 'mainstore/:identifier',
  component: MainstorePage,
  resolve: {store: MainStoreResolve},
},

Component.ts file:

ngOnInit() {
   this.page = 'Store';
   this.products = this.route.snapshot.data.store.products;
   this.store = this.route.snapshot.data.store.storeDetails;
   // console.log(this.store.store_name);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM