I'm new to front end and svelte and experimenting with some things.
I have the following counter component that has increment/decrement button for the items:
Counter.svelte
<script>
export let amount = 0;
function increment() {
amount = 1;
}
function decrement() {
if (amount > 0) {
amount -= 1;
}
}
</script>
<button on:click={decrement}>-</button>{amount}<button on:click={increment}> </button>
App.svelte
<script>
... import stuff
let items=[{ //data from rest
id: 1,
name: potato,
price: 5
}, {
id: 2,
name: garlic,
price: 3
}, {
id: 3,
name: rice,
price: 10
}];
function purchase() {
//TODO use JSON generated in POST
}
</script>
{#each items as item}
{item.name} <Counter></Counter>
{/each}
<button on:click={purchase}>Purchase</button>
How do I generate the following JSON, when the amount selected for the item is not 0 after I click the button? (assuming garlic amount is 0)
[{
id: 1,
name: potato,
price: 5,
amount: 30
},{
id: 3,
name: rice,
price: 10,
amount: 400
}];
CodePudding user response:
It's possible to bind a value inside the #each
loop to a property of the single item
{#each items as item}
{item.name} <Counter bind:amount={item.amount}/>
{/each}
The property doesn't exist yet but since you have a default value set inside Counter
export let amount = 0;
it will be initialized with zero. All changes to the amounts will then change items
directly. So inside purchase
just filter items
for the ones with an amount
function purchase() {
const itemsWithAmount = items.filter(i => i.amount > 0)
console.log(itemsWithAmount)
}
<script>
import Counter from './Counter.svelte'
let items=[{
id: 1,
name: 'potato',
price: 5
}, {
id: 2,
name: 'garlic',
price: 3
}, {
id: 3,
name: 'rice',
price: 10
}];
$: console.log(items)
function purchase() {
const itemsWithAmount = items.filter(i => i.amount !== 0)
console.log(itemsWithAmount)
}
</script>
<ul>
{#each items as item}
<li>
{item.name} <Counter bind:amount={item.amount}/>
</li>
{/each}
</ul>
<button on:click={purchase}>Purchase</button>
CodePudding user response:
You probably would want to initialize the amount
property of all the items to 0
after getting the data, then it can be bound to the Counter
:
<Counter bind:amount={item.amount} />
bind
propagates changes from the component to the item objects.
In purchase
you then just have to filter the items, something like:
const toBuy = items.filter(x => x.amount > 0);