lmngn23
lmngn23

Reputation: 521

Add background image based on element width in Angular

I have the following mat-card component in Angular that display the information of each prof object:

<mat-card class="mat-elevation-z4">
      <mat-card-header>
        <mat-card-title>{{prof["fullName"].length > 15 ? prof['fullName'].slice(0, 15) + '...' : prof['fullName']}}</mat-card-title>
      </mat-card-header>
</mat-card>

I would like to know if I can add the profile picture from prof['imageLink'] (which is an image link) based on the current width of the mat-card. So if the mat-card reaches a certain height, it will display the image, otherwise not.

I know the @media query could be helpful, but I'm displaying a list of prof, which has unique image link for each prof

I would really appreciate any help.

Upvotes: 0

Views: 236

Answers (1)

Vimal Patel
Vimal Patel

Reputation: 3055

You can wrap your card inside a container div and then you can get the width of card using offsetWidth.

@ViewChild("myIdentifier") myIdentifier: ElementRef;

<div #myIdentifier>
    <mat-card class="mat-elevation-z4">
        <mat-card-header>
            <mat-card-title>{{prof["fullName"].length > 15 ? prof['fullName'].slice(0, 15) + '...' : prof['fullName']}}
            </mat-card-title>
        </mat-card-header>
        <img [class.hide]="width < 500" mat-card-image [src]="prof.imageLink" alt="Photo of a Shiba Inu">
   </mat-card>
</div>

You need to use ngAfterViewInit event to get the width as only after view is rendered you can get the exact width.

ngAfterViewInit() {
    this.width = this.myIdentifier.nativeElement.offsetWidth;
    this.cdr.detectChanges();
  }

Then based on your predefined width you can show hide the profile picture.

<img [class.hide]="width < 500" mat-card-image [src]="prof.imageLink"/>

As we updating the view after view initializated. we will get an error "Expression ___ has changed after it was checked".

To get rid of that error we need to manually invoke change detection.

this.cdr.detectChanges();

Edit1: Handle page resize.

If you want to make this responsive(on page resize) you need to detect/bind browser resize event and update the width property in that and it will work.

ngOnInit() {
    this.resizeObservable$ = fromEvent(window, "resize");
    this.resizeSubscription$ = this.resizeObservable$.subscribe(evt => {
        this.width = this.myIdentifier.nativeElement.offsetWidth;
    });
}

Make sure to destory the subscription in component onDestroy method.

ngOnDestroy() {
    this.resizeSubscription$.unsubscribe()
}

Demo updated with latest code changes.

Upvotes: 1

Related Questions