0

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.

2
  • you can show based on width or height if yes is it going to be a fixed value? Commented Dec 18, 2020 at 16:06
  • Yes if the width reaches a fixed value then show the picture from the image link Commented Dec 18, 2020 at 16:23

1 Answer 1

1

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.

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

2 Comments

Thank you for your answer, but this only works when I reload the webpage, is there anyway that I can make it work when I resize the webpage? Like I have a sidebar component, when opening, it will decrease the width of the mat-card.
I tried with this code: ` toggleSideNav() { this.opened = !this.opened; this.width = this.myIdentifier.nativeElement.offsetWidth; console.log(this.width); this.cdr.detectChanges(); }` But somehow it always console log out the previous value (value before opening, which is bigger), not the current value of the width,

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.