Zze
Zze

Reputation: 18865

ngStyle in *ngFor not working

I am trying to dynamically set the left of a div depending upon the quantity of elements in an array. To do this, I am using the calc() method in my [ngStyle], where data.questions is an array of objects on which I draw from.

To prove that the calculation works, I added it into a <p> for debug purposes.

I have the following in my html:

<div id="progress">
    <div *ngFor="let question of data.questions; let i = index;"
         [ngStyle]="{'left': 'calc('+(i / data.questions.length * 100) + (1 / (data.questions.length * 2) * 100)+'%)'}">
        <p>{{(i / data.questions.length * 100) + (1 / (data.questions.length * 2) * 100)}}%</p>
    </div>
</div>

Below is the rendered content. You can see that the [ngStyle] is only working for the first of the 3 generated divs. Why is this the case?

<div _ngcontent-ydx-7="" id="progress" ng-reflect-ng-style="[object Object]" style="border-color: rgb(127, 167, 187);">
    <div _ngcontent-ydx-7="" ng-reflect-ng-style="[object Object]" style="left: calc(16.6667%);">
        <p _ngcontent-ydx-7="">16.666666666666664%</p> 
    </div>
    <div _ngcontent-ydx-7="" ng-reflect-ng-style="[object Object]">
        <p _ngcontent-ydx-7="">49.99999999999999%</p>
    </div>
    <div _ngcontent-ydx-7="" ng-reflect-ng-style="[object Object]">
        <p _ngcontent-ydx-7="">83.33333333333331%</p>
    </div>
</div>

note: I spent a considerable time trying to make a plunkr for this, however it kept giving me errors with using data.questions in my ngFor even though this definitely works as proved above (my plunkr skills are a work in progress....).

Below is a simplified version of data.questions for people to play with...

private questionOptions: string[] = [
  `Strongly Agree`,
  `Agree`,
  `Slightly Agree`,
  `Slightly Disagree`,
  `Disagree`,
  `Strongly Disagree`
];

private data = {
  questions: [{
      text: `Great service makes a difference to the customer.`,
      options: [{
          text: this.questionOptions[0],
          score: 3
        },
        {
          text: this.questionOptions[1],
          score: 2
        },
        {
          text: this.questionOptions[2],
          score: 1
        },
        {
          text: this.questionOptions[3],
          score: -1
        },
        {
          text: this.questionOptions[4],
          score: -2
        },
        {
          text: this.questionOptions[5],
          score: -3
        }
      ]
    },
    {
      text: `Great service can be provided every time we interact with our customers. `,
      options: [{
          text: this.questionOptions[0],
          score: 3
        },
        {
          text: this.questionOptions[1],
          score: 2
        },
        {
          text: this.questionOptions[2],
          score: 1
        },
        {
          text: this.questionOptions[3],
          score: -1
        },
        {
          text: this.questionOptions[4],
          score: -2
        },
        {
          text: this.questionOptions[5],
          score: -3
        }
      ]
    },
    {
      text: `Customer facing staff have more impact on providing great service than I do.`,
      options: [{
          text: this.questionOptions[0],
          score: -3
        },
        {
          text: this.questionOptions[1],
          score: -2
        },
        {
          text: this.questionOptions[2],
          score: -1
        },
        {
          text: this.questionOptions[3],
          score: 1
        },
        {
          text: this.questionOptions[4],
          score: 2
        },
        {
          text: this.questionOptions[5],
          score: 3
        }
      ]
    }
  ]
};

Upvotes: 0

Views: 4036

Answers (2)

Yoav Schniederman
Yoav Schniederman

Reputation: 5391

<div id="progress" *ngIf="data">
    <div *ngFor="let question of data.questions; let i = index;"
         [ngStyle]="{'left': 'calc(i)'}">
        <p>{{(i / data.questions.length * 100) + (1 / (data.questions.length * 2) * 100)}}%</p>
    </div>
</div>



calcLeftPostion(index: number){
     let dataLength = this.data !== null ? this.data.questions.length : 0;
     return ((i / dataLength  * 100) + (1 / (dataLength  * 2) * 100))+ '%';
}

Upvotes: 0

yurzui
yurzui

Reputation: 214335

Before

calc(016.666666666666664%)

calc(33.3333333333333316.666666666666664%)

calc(66.6666666666666616.666666666666664%)

They are not valid styles (except the first iteration). You need to wrap your calculations in brackets like

'calc(' + // string

((i / data.questions.length * 100) + (1 / (data.questions.length * 2) * 100)) + // number

'%)' // string

Summary

[ngStyle]="{'left': 'calc('+((i / data.questions.length * 100) + (1 / (data.questions.length * 2) * 100))+'%)'}"

Plunker Example

Upvotes: 3

Related Questions