Kirk
Kirk

Reputation: 5077

How to use multiple Angular component in a loop

I am creating a pop notification panel where I will show all unrated purchase order deliveries. I am not sure how I would use *ngFor to loop it.

I have a system where a user can go and star rate their item order delivery. Every order has its rating page where they rate the order. This is done using a custom component (Star Rating Component).

Question is it works just fine when using it in a page, but now I also need to remind users via notification panel that there are unrated orders, ex "please rate them right away." This is done using a modal with repeated rating component.

Now, when I loop all the unrated orders, it shows as expected but, when I rate one order, all other orders also changing its ratings. How do I overcome this?

<ng-container *ngFor="let task of unratedOrders; let i = index">
                            <div class="col-md-3">
                                <div class="card">
                                    <div class="card-body r-wrapper__body">
                                        <div>
                                            <div class="avatarx">

                                            </div>
                                            <div class="header">
                                                <h3 class="card-title">Rate task {{task.orderId}}</h3>

                                            </div>
                                        </div>
                                        <div class="star-rating-size">
<!-- The rating component is here -->
                                            <star-rating id="{{task.orderId}}-rating-component" (ratingChange)="changeRating($event)" [controlIndex]="i" [ratings]="ratings" [(rating)]="supplierRating.ratingId"></star-rating>
                                        </div>
                                        <div class="r-info">
                                            <div class="r-info__icon">
                                                <i class="fa fa-info-circle" aria-hidden="true"></i>
                                            </div>
                                            <p>
                                                <span *ngIf="selectedRating"><b>{{selectedRating?.ratingHeader}}</b> - {{selectedRating?.ratingDesc}}</span>
                                            </p>
                                        </div>
                                        <textarea class="r-comment" name="" placeholder="Write a short comment.." id="" cols="30" rows="2" [(ngModel)]="supplierRating.description"></textarea>
                                        <button type="button" class="btn btn-sm" (click)="changeETA(task)">Change ETA</button>
                                        <button type="button" class="btn btn-primary btn-sm" (click)="submitRating($event)">Submit rating</button>
                                    </div>
                                </div>
                            </div>
                        </ng-container>

PS: Following is the component

Also, the ratings that I pass it to the component is the data for rating loop, usually 5 ratings will be passed as an object. This then renders 5 starts in the component.

<fieldset class="rate" id="rate-{{controlIndex}}" [class.readonly]="readonly">
    <ng-container *ngFor="let star of ratings; let i = index">
        <input type="radio" id="rating-{{ratings.length-i-1}}-{{controlIndex}}" name="rating-{{controlIndex}}" [checked]="(star.id == rating)" />
        <label [class.half]="(i%2)==1" for="rating-{{ratings.length-i-1}}-{{controlIndex}}" (click)="updateRating(star.id)"></label>
    </ng-container> 
</fieldset>

enter image description here

As you can see I have done all the tricks inserting unique id etc, but no luck!

Upvotes: 0

Views: 1091

Answers (5)

Dileep Kumar Kottakota
Dileep Kumar Kottakota

Reputation: 127

It could be issue with your actual star rating component. May be while adding rating they may not have any id type differentiation. Code would help for exact analysis.

Your code should be like below

unratedOrders - [{
orderId:1234
ratings:[{},{}]
}]


<div class="star-rating-size">
    <star-rating [ratings]="task.ratings" (ratingChange)="changeRating($event,task)"  id="{{task.orderId}}-rating-component"  [controlIndex]="i"  [(rating)]="supplierRating.ratingId"></star-rating>
</div>

changeRating(event, selectedTask) {
    loop through unratedOrders and assing value to selected task
}

Upvotes: 1

Dileep Kumar Kottakota
Dileep Kumar Kottakota

Reputation: 127

It could be issue with your actual star rating component. May be while adding rating they may not have any id type differentiation. Code would help for exact analysis.

Your code should be like below

unratedOrders - [{
orderId:1234
ratings:[{},{}]
}]


<div class="star-rating-size">
    <star-rating #starRating id="{{task.orderId}}-rating-component" (ratingChange)="changeRating($event,task)" [controlIndex]="i" [ratings]="task.ratings" [(rating)]="supplierRating.ratingId"></star-rating>
</div>

changeRating(event, selectedTask) {
    loop through unratedOrders and assing value to selected task
}

Upvotes: 1

hackape
hackape

Reputation: 19957

Now i don't see how you update your ratings value, but i see you bind to the SAME ratings in every <star-rating> element, since you use custom directive i cannot guess the internal work. But it looks suspicious to me.

Upvotes: 1

Abhay Naveen
Abhay Naveen

Reputation: 71

[ratings]="ratings", shouldn't this be [ratings]="task.ratings" . Since it's in a loop i guess you need to assign the value of the rating to the current iterating element. Probably why all values are changing when you change one.

Upvotes: 1

Toon
Toon

Reputation: 66

idk if u really have to use your component, if not, there's a module from ng-bootstrap for start rating that's really simple to use here and u could store your rates easily in an array

Upvotes: 1

Related Questions