Sveltekit component doesn't update filtered object on pagination

76 Views Asked by At

I'm new to Svelte and struggling with the reactive nature of passing variables to a component.

I have:

  • votes = json object holding all votes for all actors
  • /actors = paginated display of pages with variables passed to URL via goto (i.e. /actors?page=0&limit=10)

In actors/+page.svelte I have a loop which passes in a single actor's vote from a json object of all the actors' votes:

{#each data.actors as actor}
       <Person actor={actor} vote={votes.length ? votes.filter(function (entry) {
            if(entry.type === 'actor' && entry.typeId === actor.id){
                  return true;
            }
            return false;
            }):{}} hasSession={!!data.session}/>
{/each}

And the component Person.svelte does some logic to calculate:

    export let actor;
    export let vote; //the vote json object (if exists)
   
    let voted = vote.length ? true : false;
    let lastVote = vote.length && typeof(vote[0].vote) ? vote[0].vote :  false; 
    
    let voteAvg = actor.voteAvg;
    let voteTotal = actor.voteTotal;
    
    
    let captureVote = async function(e){
        
        const newVote = e.target.value;
        
        //update the card
        voteAvg = voteAvg - lastVote + parseInt(newVote);
        
        const response = await fetch('/vote', {
            method: 'POST',
            body: JSON.stringify({ 
                type:'actor',
                actorId: actor.id, 
                vote:newVote,
                lastVote:lastVote,
                voted:voted
            }),
            headers: {
                'Content-Type': 'application/json'
            }
        });
        
        if( !voted ){
            console.log('fist vote');
            voteTotal++;
            voted = true;
        }
        
    }

with the variables being passed into the html as follows (Using Skeleton.dev components):

<div class="p-4 space-y-4">

        <a href="/actor/{actor.id}">
            <h4 class="h5 h-14 max-h-full overflow-hidden" data-toc-ignore="">{actor.name}</h4>
        </a>
        
        <div class="flex w-100 items-center space-x-4">
            <div class="flex-auto flex justify-between items-center">
                <span class="chip variant-filled">{voteAvg}</span>
                <small class="small">{voteTotal} votes</small>
            </div>
        </div>

    </div>
    
    <hr class="opacity-50">
    <footer class="p-2 w-100">
        
            <RadioGroup background="none" display="flex" border="none" active="variant-filled-primary" hover="hover:variant-soft-primary">
                <RadioItem bind:group={lastVote}  on:click={captureVote} name="justify" value={1}><i class="fa-regular fa-thumbs-up"></i></RadioItem>
                <RadioItem bind:group={lastVote} on:click={captureVote} name="justify" value={-1}><i class="fa-regular fa-thumbs-down"></i></RadioItem>
                <RadioItem bind:group={lastVote}  on:click={captureVote} name="justify" value={0}><i class="fa-regular fa-minus"></i></RadioItem>
            </RadioGroup>
            
    </footer>

Everything works as expected as far as paginating through actors - their details update as page/limit changes - however the "vote" object being passed in remains static to the order it was passed into on the initial load. A console.log inside Person component demonstrates that it isn't firing the calculation logic again, and/or the filtering logic is not being passed in.

I tried to change the variables in Person.svelte to be reactive - i.e.

$: voted = vote.length ? true : false;
$: lastVote = vote.length && typeof(vote[0].vote) ? vote[0].vote :  false; 
$: voteAvg = actor.voteAvg;
$: voteTotal = actor.voteTotal;

while this did initially appear to solve the problem (proper votes were displaying as i paginate through results), the component's logic of casting a vote and updating things like voteAvg and voteTotal no longer worked.

Not sure what I'm doing wrong but your help is greatly appreciated! :)

0

There are 0 best solutions below