EmilTholin / svelte-routing

A declarative Svelte routing library with SSR support
MIT License
2.02k stars 178 forks source link

Force re-render of route on demand #151

Closed quantuminformation closed 4 years ago

quantuminformation commented 4 years ago

I have this profile route that runs its code when navigated to from another route, however, if I select another user from the use:link it doesn't run if its currently on .

On the left is the profile logic I need to run again for the route <Route path=":username" component="{Profile}" /> image

quantuminformation commented 4 years ago

As a stopgap I decided to react to it and call wrap the route logic somewhere in there image

quantuminformation commented 4 years ago

fyi this was my code:

<script>
    import {
        getDBUserByUsername,
        addConnection,
        amIFollowing,
        unFollowUser,
    } from "../firebaseBackend"
    import { log } from "../util/logging"
    import DefaultSpinner from "../components/DefaultSpinner.svelte"
    import { userDataStore } from "../stores/userDataStore"
    import KnowledgeGraph from "../components/KnowledgeGraph.svelte"

    let isOwnProfile = false
    export let user
    export let isFollowing = false
    export let username // comes from the route

    $: {
        log(`username changed to ${username}`)
        routeLogic()
    }

    //  export let viewingAnonymously = !!firebase.auth().currentUser // not logged in //todo infuture decide if we want to allow this
    let promise

    function routeLogic() {
        // check if user is current user, if so just resolve the promise with the local data, or get it from the db
        if ($userDataStore && $userDataStore.username === username) {
            isOwnProfile = true
            user = $userDataStore
            promise = Promise.resolve($userDataStore)
            log(`Profile page for logged in user ${username}, skipping data retrieval`)
        } else {
            log(`loading profile data for username ${username}`)

            async function promiseWrap() {
                user = await getDBUserByUsername(username)
                if ($userDataStore) {
                    isFollowing = await amIFollowing(user.uid)
                }
                isOwnProfile = false

                //todo what to return here?
                return true
            }

            promise = promiseWrap()
        }
    }

    const follow = async (event) => {
        let result = await addConnection(user)
        if (result) {
            isFollowing = true
        }
    }
    const unFollow = async (event) => {
        let result = await unFollowUser(user)
        if (result) {
            isFollowing = false
        }
    }
    //1st time call on this route visit
    routeLogic()
</script>

<div class="container pt-4 px-3 mx-auto flex flex-wrap flex-col items-center">

    {#await promise}
        <DefaultSpinner />
        <!--todo can we get rid of result here as its no used?-->
    {:then result}
        <img
            src="{$userDataStore.gravatarURL || 'http://www.gravatar.com/avatar/?d=identicon&s=100'}" />
        <h1>{user.displayName || 'User has not set a display name'}</h1>
        {#if isOwnProfile}
            <span>It's you!</span>
        {/if}

        {#if $userDataStore && !isOwnProfile}
            {#if isFollowing}
                <button
                    class="bg-white hover:bg-red-100 text-gray-800 font-semibold py-2 px-4 border
                    bg-red-300 border-gray-400 rounded shadow"
                    on:click="{unFollow}">
                    Remove as mentor
                </button>
            {:else}
                <div>
                    <button
                        title="Once you click add they will be will be sent verification"
                        class="bg-white hover:bg-green-100 text-gray-800 font-semibold py-2 px-4
                        border bg-green-300 border-gray-400 rounded shadow"
                        on:click="{follow}">
                        Add as mentor
                    </button>
                    <button
                        title="Once you click add they will be will be sent verification"
                        class="bg-white hover:bg-green-100 text-gray-800 font-semibold py-2 px-4
                        border bg-blue-300 border-gray-400 rounded shadow"
                        on:click="{follow}">
                        Add as mentee
                    </button>
                </div>
            {/if}
        {/if}
        <KnowledgeGraph />
    {:catch error}
        <p style="color: red">error: {error}</p>
    {/await}
</div>