saiy2k
saiy2k

Reputation: 1862

stenciljs: Issue with slot

I have created a simple web (stencil) component AuthGuard, not to be be confused with Angular's AuthGuard.

The purpose of this component is to check if the user is logged in.

The component code is as follows:

import { Component, Host, h }   from    '@stencil/core';
import { Build, State       }   from    '@stencil/core';

import { AuthService        }   from    'auth/auth.service';
import { ConfigService      }   from    'common/config.service';

@Component({
    tag                         :   'auth-guard',
    styleUrl                    :   'auth-guard.css',
    shadow                      :   true,
})
export class AuthGuard {

    @State() canRender          :   boolean             =   false;

    componentWillLoad() {
        if (Build.isBrowser) {
            const timerId       =   setInterval(() => {
                if (AuthService.isInitialized) {
                    AuthService.vol$.subscribe(_u => {
                        this.canRender= true;
                    });
                    clearInterval(timerId);
                }
            }, ConfigService.loadTime);
        }
    }

    render() {
        console.log('auth guard :: render', this.canRender, AuthService.me);
        return (
            <Host>
                { 
                    this.canRender ? (
                        AuthService.me && AuthService.me.id.length > 0 ? (
                            <slot></slot>
                        ) : (
                            <ion-button
                                href="/signup"
                                routerDirection="forward"
                                color="danger">
                                Signup
                            </ion-button>
                        )
                    ): null
                }
            </Host>
        );
    }

}

Now in the other file, I use the following code:

<auth-guard slot='end'>
    <volunteer-mini volunteer={AuthService.me}></volunteer-mini>
</auth-guard>

With this what I am expecting is

But seems when this.canRender is false, it tried to render volunteer-mini the slot HTML, which is a problem. Since volunteer-mini internally depends on AuthService.me, which is not yet initialized.

But once this.canRender becomes true, other 2 scenarios are working fine.

Upvotes: 0

Views: 1592

Answers (1)

max
max

Reputation: 338

It's in general a bad idea to write an auth-guard using stencil. The core problem is that your slot exists before your component has initialized.

Therefor, using your current code, you'd have to manually remove the slot after you decided that you don't have the rights.

Additionally, if you do not define a slot position, but still provide a slot-content in your parent, it will still be appended to your inner children.

To resolve this problem, you can refactor your component to an function, like <Host>, but this has other pits to consider.

Upvotes: 2

Related Questions