Unable to remove items using splice within for loop in Angular - arrays

I am trying to remove an item from an existing array using splice but is not working as expected. I even tried using filter instead of splice but got the same output. Can some one please take a look at the functionality here and help me figure out the issue.
Please try to add the available items here - https://08b11a0437.stackblitz.io/products then navigate to the cart page and try to remove each item. The items are not getting removed as expected.
Relevant Code is available in cartservice.ts, cartcomponent.ts(removeProductFromCart()) and cartcomponent.html - https://stackblitz.com/edit/08b11a0437?file=app%2Fcart%2Fcart.component.ts

The problem is you are removing items from an array in cartService, but for the UI you are using values from the products array.
A quick fix is to reload your products array. Just add the following code in your removeProductFromCart function in ShoppingCartComponent. Add it at the end of the function.
this._cartService.getAddedProducts().subscribe((data: IProduct[]) => {
this.products = data.map(item => item[0]);
});
Apart from that there is another issue. You are hiding items in ShoppingCartComponent html using *ngIf="removeItemId !== product.id". Consider you have three products (with id 1,2 and 3) in your cart, when the first products is removed, removeItemId will have 1, so the first product will be hidden. But when the user removes the second product, removeItemId will be set to 2, and now product one will be visible.

Related

Is there any alternative to each() for this scenario

So I have a list of buttons on my webpage and I have to iterate through the list of those buttons and based on the inner text value I have to click the matching button. Now the number of buttons are dynamic, so sometimes it can be 5 or sometimes it can be 6 or something else. Now I have written a code with each() and this works perfectly -
cy.get('buton').each(($ele) => {
if ($ele.text().trim() === "insurance") {
cy.wrap($ele).click()
}
})
My question is are there any other way this logic can be written(without using each).
You can select the button directly
cy.contains('button', 'insurance').click()
You can use filter() in combination with contains() to get your desired button and click it.
cy.get('button')
.filter(':contains("insurance")')
.click()

react-animated-css not fired when list is updated

I am using react-animated-css, for simple animation in react. I have a list which I am rendering in a <ul> tag. I am adding animation to the first element of the list.
This list is getting updated every 3 seconds. And new element is added at the first position in the array.
The problem is, on load the animation is happening but not on update.
Here is full code : https://codesandbox.io/embed/ecstatic-cloud-qdpcj
I am not able to create a tag with 'react-animated-css' name as I am not eligible. It would be helpful if someone creates one for this.
You must define a key property for every element in a map. If you do not define one the array index is the default key. So the first element with key 0 will be reused after each render and only the last one will be added. If you define a key, the redrawing will based on the key value, and the first one will be added.
{items.map((d, i) => {
if (i === 0) {
return (
<Animated
key={d}
animationIn="bounce"
animationOut="flash"
animationInDuration={1000}
animationOutDuration={1000}
isVisible={true}
>
<li>{d}</li>
</Animated>
);
Here is the example: https://codesandbox.io/s/pedantic-darkness-vgp3f
From my point of view "react-animated-css" this library is not getting re-rendered once the state gets updated.
I have tried it with simple css animation property "#keyframe" and is working fine and getting re-rendered when state changes.
Code-sandbox link :
https://codesandbox.io/s/suspicious-dijkstra-h1q7u

Angular select multiple not setting selected items

Scenario is quite simple. I have edit view which comprises of select element with multiple selection. Select element looks as follows
<select class="selectpicker" multiple
ng-model="UserBeingEdited.UberTypes"
ng-options="uberType.Id as uberType.Name for uberType in UberTypes"></select>
</div>
If I press edit for specific user then showEditModal function is called and edit pop up shows up. User has his own UberTypes objects selected so I pick theirs Ids and assign to UserBeingEdited.UberTypes.
$scope.UserBeingEdited = { UberTypes: []};
$scope.showEditModal = function (user) {
for (var i = 0; i < user.UberTypes.length; i++) {
$scope.UserBeingEdited.UberTypes.push(user.UberTypes[i].Id);
}
$("#editUserModal").modal("show");
};
Unfortunately they are not selected, no matter what. Suprisingly, if I set values to property UserBeingEdited by the time of declaring then it works, items are selected.
$scope.UserBeingEdited = { UberTypes: [1,2]}; //this works
It seems like angular does not refresh selected items within UI.
EDIT:
I have two items: Uber1 and Uber2. Both items are selected but view does not reflect it. If I open drop down menu and select Uber2 it shows Uber1 selected, apparently Uber2 was selected and another click was treated as unselection. The same happens when I click Uber1 first, Uber2 shows as selected.
As above picture depicts, Uber2 is highlighted since I have just clicked it but it shows Uber1 as selected. Both were selected in User's UberTypes but view just simply does not mark them as selected.
http://jsfiddle.net/upusq8ah/7/
I use bootstrap-select.js for select element and presumably this library causes such an error since without including it, it works fine.
Solution
After a while of struggle, I accidentally ran into below workaround. You need to call refresh on selectPicker and this has to be delayed otherwise it will bring no effect.
setTimeout(function () {
$('.selectpicker').selectpicker('refresh');
}, 100);
$("#editUserModal").modal("show");

Select multiple values from ng-repeat and pass to new view with AngularJS

Okay, I'm in a quandary..
The idea: A web app, that can show a list of all the players (in my DB). You should then be able to pick 2 players on the list and press a play button. Then be passed on to a new view WITH the two selected players..
So, what i need is to be able to select to players from my ng-repeat list and then pass their information from my JSON on to the next view.
For now, I just wanna print em' on the next view. I'll be able to figure out how to use them for the game myself once this is done.
Anybody? :(
The best way to select more than one value is using the $index associated with the every element. Push all the selected value into the array, and check for the index of the value in the array.
In Your view:
ng-class="{sel: selected.indexOf($index) >= 0 }"
In your controller
$scope.select= function(index) {
$scope.selected.push(index);
};
working demo:
http://jsfiddle.net/chella89/3G7Kd/173/

In Backgrid, how can I change pageSize with a select input?

I'm trying to add a select box to a Backgrid.Grid in order to fire a function that will reset the state: {pageSize} to the value the user selects. But I can't figure out how or where to bind the events to the grid.
My understanding is that the element needs to be part of the view (which I believe is the Backgrid.Grid), so I added the select box to the footer of the grid and gave it an id and tried adding an events parameter and matching function to it, but it does nothing.
So, in my footer I have
select id="changePageSize"
And in the grid
events: {
'change #changePageSize' : 'changePageSize'
},
changePageSize: function(){ console.log('hooray!');}
I believe my approach is completely wrong at this point but can't find anything to direct me down the correct path.
What I ended up doing was adding the event listener and function to the backgrid-paginator extension.
Added the select box to the _.template('...
_.template('...<div class="page-size"><select name="pageSize" class="pageSize"><option...');
Under events I added:
'change select.pageSize' : 'changePageSize'
And then created the function:
changePageSize: function(e){
e.preventDefault();
this.collection.state.pageSize = Math.floor(e.currentTarget.value);
this.collection.reset();
},
It makes sense to make this function and its display optional and to also allow a developer to assign an array to generate custom option values. When I get time.
Regarding Duffy Dolan's answer: everything si great in your example, except if you are on let's say on third page and select to have all results only on one page, you get an error.
You just need to add:
this.collection.getPage(1); // it will always select first page

Resources