0

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!

6
  • You are using Angular NOT AngularJS Commented Apr 9, 2019 at 6:49
  • My bad, but that's not the point. Commented Apr 9, 2019 at 6:50
  • If possible then provide stackblitz Commented Apr 9, 2019 at 6:53
  • I am afraid I can't replicate it by simplifying it. Is there anything else I can help you with? Commented Apr 9, 2019 at 6:57
  • @Kirk no need of actual code just sample testable code Commented Apr 9, 2019 at 7:01

5 Answers 5

1

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

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

1 Comment

Welcome to StackOverflow, btw its good to know, the component is cool but I don't have time to re-write the entire system again and test it. Is there any workaround for my crappy code here?
1

[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.

2 Comments

Sorry for confusing code, but that's is an array sending to the component for looping all 5 starts. inside the component, I am iterating the array to render 5 starts. So that's why Ratings.
You would still need a reference of "task" in "unratedOrders" to update the ratings for that one task. Try binding the rating to task.
1

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.

2 Comments

Sorry for confusing code, but that's is an array sending to the component for looping all 5 starts. inside the component, I am iterating the array to render 5 starts. So that's why Ratings.
See Abhay Naveen's answer. I got same thought
1

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
}

Comments

1

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
}

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.