2

I get the concept of how to get a simple image into the cell like this

<img [src]="element.imageUrl" />

But i am wondering what the best way would be to display a collection of stars. Lets say i have a field called overallRaiting which holds a value of 0 to 5. If the value is 0 i want to show no star , if its 1 then 1 star ,if 2 then 2 stars and so on. Here is what i came up with so far which works but hope there might be better way.

    <ng-container matColumnDef="imageUrl">
    <th mat-header-cell *matHeaderCellDef> Image Url </th>
    <td mat-cell *matCellDef="let element"> 
      <img *ngIf="element.overallRaiting>=1" [src]="element.imageUrl" />
      <img *ngIf="element.overallRaiting>=2" [src]="element.imageUrl" />
      <img *ngIf="element.overallRaiting>=3" [src]="element.imageUrl" />
      <img *ngIf="element.overallRaiting>=4" [src]="element.imageUrl" />
      <img *ngIf="element.overallRaiting>=5" [src]="element.imageUrl" />
  </ng-container>

Would i have to do a *ngif for each nbr or is the a cleaner more reusable way ?

Ok tried this on

          <ng-container matColumnDef="overall_rating">
            <th mat-header-cell *matHeaderCellDef> Overall Rating </th>
            <td mat-cell *matCellDef="let element"> 
                <ng-container *ngFor="let i of [].constructor(element.overall_rating)">
                    <img class="star" src="../../assets/images/basic-5-point-gold-star-beveled.jpg" />
                  </ng-container>
              {{element.overall_rating}}
              </td>
          </ng-container>

Which produces this in doc

 <td _ngcontent-snv-c2="" class="mat-cell cdk-column-overall_rating mat-column-overall_rating" mat-cell="" role="gridcell"><!--bindings={
      "ng-reflect-ng-for-of": "4"
    }--><!----><img _ngcontent-snv-c2="" class="star" src="../../assets/images/basic-5-point-gold-star-beveled.jpg"> 4 </td>

enter image description here

2 Answers 2

4

You can use *ngFor to avoid having multiple *ngIfs.

<ng-container matColumnDef="imageUrl">
    <th mat-header-cell *matHeaderCellDef> Image Url </th>
    <td mat-cell *matCellDef="let element"> 
      <ng-container *ngFor="let i of [].constructor(element.overallRating)">
        <img [src]="element.imageUrl" />
      </ng-container>
    </td>
</ng-container>

There are other ways you can repeat an element using *ngFor, but this looked simpler.

You can also abstract away this logic and create a child component which takes rating as input and displays corresponding number of stars.

<ng-container matColumnDef="imageUrl">
    <th mat-header-cell *matHeaderCellDef> Image Url </th>
    <td mat-cell *matCellDef="let element"> 
      <app-star-rating [rating]="element.overallRating"><app-star-rating>
    </td>
</ng-container>
Sign up to request clarification or add additional context in comments.

5 Comments

I tried the *ngFor in your first recomendation but it seems to no do what i expect. In my case element.overallRating is a single number which can be either 0 to 5
@NoSoup4you - What is it showing on the screen? Are you getting any error? I had corrected the spelling to Rating, it was Raiting in your question.
@NoSoup4you - Check out my edited answer. We have to use *ngFor on an iterable object, but I was using it on just a number earlier. Fixed it now.
tried new code but still dont get what i need, i updated my question with the changes and the result
@NoSoup4you - What you have should work. Check out stackblitz.com/edit/angular-material-with-angular-v5-ldaaqk where I demonstrated this. Also, please replace the code there with yours and let me know when you are done, I'll take a look.
0

Ok based on @Nikhil answer the folowing code works for me now. The issue in my case ended being that the number was in string format which created only a single loop.

 <ng-container matColumnDef="overall_rating">
            <th mat-header-cell *matHeaderCellDef> Overall Rating </th>
            <td mat-cell *matCellDef="let element"> 
                <ng-container *ngFor="let i of [].constructor(NumberConverter(element.overall_rating))">
                    <img class="star" src="../../assets/images/basic-5-point-gold-star-beveled.jpg" />
                  </ng-container>
              </td>
          </ng-container>

then on the controller i added the function

NumberConverter(value: any) {
  if (value === null || value === undefined || typeof value === 'number') {
      return value;
  }

  return parseFloat(value.toString());
}

that made sure it always returned the value in number format if it was posible

Comments

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.