Martnart
Martnart
Explore posts from servers
SSolidJS
Created by Martnart on 8/28/2023 in #support
Building with SSR false starts (and doesn't close) listeners
In my app I create a WebsocketServer on Port 3001. If I run npm run build with default SSR setting (ssr: true) everything works like a charm. However, turning off ssr, the WebsocketServer gets started and not closed => EADDRINUSE error. Cannot run dev or start afterwards. After forcefully terminating the process, I can run start with the built files and it works. Any suggestions on how to avoid this?
18 replies
SSolidJS
Created by Martnart on 4/22/2023 in #support
Hydration issues on navigation while hydration is ongoing
With a structure like this, navigation is enabled before hydration is complete.
<Sidebar />
<Suspense>
<Outlet />
</Suspense>
<Sidebar />
<Suspense>
<Outlet />
</Suspense>
While hydrating, users can already use the sidebar to navigate to different routes. However, this leads to hydration errors and this also leads to an issue where two A components are "active" at the same time, i.e. "activeClass" is applied to two link components simultaneously. Is there anything I can do to prevent this? Edit: Might well be that I mis-analyzed the circumstances of this. Please excuse me if that's the case. The problem is very real, though 😮
1 replies
SSolidJS
Created by Martnart on 4/11/2023 in #support
RouteDataArgs Type Error for nested RouteData
// Root
export function routeData(args: RouteDataArgs) {
return () => 'foo'
}

// Child
export function routeData(args: RouteDataArgs<typeof RootRouteData>) {
return args.data() ? args.data() : () => 'bar'
}

// Grandchild
export function routeData(args: RouteDataArgs<typeof ChildRouteData>) {
return args.data() // <= TypeError. An Argument for "args" was not provided.
}
// Root
export function routeData(args: RouteDataArgs) {
return () => 'foo'
}

// Child
export function routeData(args: RouteDataArgs<typeof RootRouteData>) {
return args.data() ? args.data() : () => 'bar'
}

// Grandchild
export function routeData(args: RouteDataArgs<typeof ChildRouteData>) {
return args.data() // <= TypeError. An Argument for "args" was not provided.
}
Wha'ts happening here? I tried to reproduce this in Stackblitz and couldn't. I'm guessing some TS config option maybe as type inference seems a bit messed up. https://stackblitz.com/edit/solid-ssr-vite-pcbdkr?file=src%2Froutes%2Findex.tsx However, locally, routeData return types are accurate and I get above error for this kind of structure.
3 replies
SSolidJS
Created by Martnart on 4/10/2023 in #support
Make routeData blocking
Following scenario:
(app).tsx
(app)/
route.tsx
(app).tsx
(app)/
route.tsx
(app).tsx
export const routeData = () => {
return createServerData$(async (_, { request }) => {
const user = await verifyUser(request)
if (!user) throw redirect('/login')
return user
})
}
export const routeData = () => {
return createServerData$(async (_, { request }) => {
const user = await verifyUser(request)
if (!user) throw redirect('/login')
return user
})
}
route.tsx
export const routeData = () => {
return createRouteData(() => {
return someDataFetch()
})
}
export const routeData = () => {
return createRouteData(() => {
return someDataFetch()
})
}
Everything underneath (app) layout should be protected by auth. However, if I have it like this, the fetch of my route starts before the user has been verified. What is the best way to overcome this, without having to go into every single routeData across my app and wrap everything inside some kind of effect that tracks some global user. Basically, is there a way to make some part of a route blocking further execution until its data has resolved?
4 replies
SSolidJS
Created by Martnart on 3/29/2023 in #support
document is not defined in HMR
I have some logic that is running in onMount and onCleanup that adds/removes a data-attribute from an element. It works. However when I make a change somewhere in my project, I get document is not defined error from HMR. It seems to be triggered by cleanNode so I am pretty sure it's from the onCleanup. The code itself looks like this shouldn't happen though because I use optional chaining. Any ideas?
onMount(() => {
const outlet = document?.getElementById('main-outlet')
outlet && (outlet.dataset.actionbar = 'true')
})

onCleanup(() => {
const outlet = document?.getElementById('main-outlet')
outlet?.dataset.actionbar && delete outlet.dataset.actionbar
})
onMount(() => {
const outlet = document?.getElementById('main-outlet')
outlet && (outlet.dataset.actionbar = 'true')
})

onCleanup(() => {
const outlet = document?.getElementById('main-outlet')
outlet?.dataset.actionbar && delete outlet.dataset.actionbar
})
Thank you 🙂
4 replies
SSolidJS
Created by Martnart on 3/23/2023 in #support
Await resolution of previous routeData in nested routeData
I have a route that fetches some data.
export function routeData({ params }) {
return createRouteData(async (key) => doMyFetch(key), { key: () => params.id })
}
export function routeData({ params }) {
return createRouteData(async (key) => doMyFetch(key), { key: () => params.id })
}
In a nested route, I want to await the result of parent route data first, before doing another fetch
export function routeData({ params, data }) {
if (!data().hasAccess) return undefined
return createRouteData(async (key) => doMyOtherFetch(key), { key: () => params.id })
}
export function routeData({ params, data }) {
if (!data().hasAccess) return undefined
return createRouteData(async (key) => doMyOtherFetch(key), { key: () => params.id })
}
CSR works fine, because I navigate from the parent route and the data is available. SSR does not work. routeData apparently is running multiple times in SSR and even though my log shows that the data is there, the function still executes past the initial guard clause - probably only in the first passthrough (I get no log though :O) when the data is still undefined. How can I tell solid to wait for data() to resolve before continuing on with the function execution? I'd like to avoid wrapping everything inside memos, effects, etc., which would mess up my returntypes and adds unnecessary complexity to something that should be solvable with a simple await. I can't find any help in the docs regarding this. Thank you in advance 🙏
3 replies
SSolidJS
Created by Martnart on 3/21/2023 in #support
Ref either locally or passed via prop
I have a TextField that requires a ref to an input field.
let input: HTMLInputElement | undefined

return <div onClick={() => input?.focus()}><input ref={input} /></div>
let input: HTMLInputElement | undefined

return <div onClick={() => input?.focus()}><input ref={input} /></div>
So far so good. But in case I have a parent component that also wants to ref the input, I am no longer sure how to handle it. I have something like this
let input: HTMLInputElement | undefined

return <div onClick={() => ('ref' in props ? props.ref : input)?.focus()}><input ref={'ref' in props ? props.ref : input}/></div>
let input: HTMLInputElement | undefined

return <div onClick={() => ('ref' in props ? props.ref : input)?.focus()}><input ref={'ref' in props ? props.ref : input}/></div>
This works for outer ref, but breaks fallback inner ref. What is the correct way to handle this case? ❤️
5 replies
SSolidJS
Created by Martnart on 3/1/2023 in #support
Correct Syntax of passing a Component via prop
I have this component.
const Test = (props: ParentProps & { label?: JSXElement }) => {
return (
<div>
<Show when={props.label}>{props.label}</Show>
{props.children}
</div>
)
}
const Test = (props: ParentProps & { label?: JSXElement }) => {
return (
<div>
<Show when={props.label}>{props.label}</Show>
{props.children}
</div>
)
}
Whenever I provide a label like so
<Test label={<Test>Hello</Test>}>World</Test>
<Test label={<Test>Hello</Test>}>World</Test>
I get hydration errors. I don't see why this would be problematic other than maybe I'm using the syntax wrong? Cheers
20 replies
SSolidJS
Created by Martnart on 2/21/2023 in #support
use:clickOutside not defined
Heyhey. I copy pasted the code from https://www.solidjs.com/tutorial/bindings_directives?solved but I get a runtime error ReferenceError: clickOutside is not defined. What am I missing here? I've added the TS declaration as mentioned in the docs here https://www.solidjs.com/docs/latest/api#use___ . My linter is complaining but I don't think it would have any impact on the solid compilation anyway?
3 replies
SSolidJS
Created by Martnart on 2/19/2023 in #support
SSR Hydration error in ChildRoute with Context set in ParentRoute and intermediate Context Update
I have a ParentRoute that retrieves RouteData and uses that data to populate a Context
export default function Main() {
const data = useRouteData();

return (
<MyContext someData={data()?.anArray}>
<Outlet />
</MyContext>
)
}
export default function Main() {
const data = useRouteData();

return (
<MyContext someData={data()?.anArray}>
<Outlet />
</MyContext>
)
}
In my child route, I get hydration errors when accessed directly via SSR. With Client-side navigation it works fine.
export default function Child() {
const [someItem] = useMyContext()

return (
<Show when={someItem()} fallback={<Placeholder />} keyed>
{(item) => <p>{item}</p>}
</Show>
)
}
export default function Child() {
const [someItem] = useMyContext()

return (
<Show when={someItem()} fallback={<Placeholder />} keyed>
{(item) => <p>{item}</p>}
</Show>
)
}
Context looks like this
const TheContext = createContext([
() => undefined,
() => [],
])

export const MyContext(props: { anArray?: string[], children: JSXElement }) {
const [theArray, setTheArray] = createSignal(props.anArray || [])

const someItem = createMemo(() => theArray[0])

const theContext = [
someItem,
theArray,
]

return (
<TheContext.Provider value={theContext }>
{props.children}
</TheContext.Provider>
)
}

export const useMyContext = () => useContext(MyContext)
const TheContext = createContext([
() => undefined,
() => [],
])

export const MyContext(props: { anArray?: string[], children: JSXElement }) {
const [theArray, setTheArray] = createSignal(props.anArray || [])

const someItem = createMemo(() => theArray[0])

const theContext = [
someItem,
theArray,
]

return (
<TheContext.Provider value={theContext }>
{props.children}
</TheContext.Provider>
)
}

export const useMyContext = () => useContext(MyContext)
Any ideas what went wrong here? ❤️
4 replies
SSolidJS
Created by Martnart on 1/16/2023 in #support
Forward reference a Component's state in Template
I try to wrap a Trigger and a Display component in a state managing component like so
export function Wrapper(props) {
const [state, setState] = createSignal(false)

return (
<>
{props.children}
<div>{state()}</div>
</>
)
}

export function Main() {
return (
<Wrapper>
<button onClick={() => Wrapper.setState(v => !v)}>Click</button> // Pseudo-code - Wrapper.setState does not make sense of course
</Wrapper>
)
}
export function Wrapper(props) {
const [state, setState] = createSignal(false)

return (
<>
{props.children}
<div>{state()}</div>
</>
)
}

export function Main() {
return (
<Wrapper>
<button onClick={() => Wrapper.setState(v => !v)}>Click</button> // Pseudo-code - Wrapper.setState does not make sense of course
</Wrapper>
)
}
Is this possible? Background is, I want the triggering component to be dynamic. Might be a button, checkbox, input field, etc. And I would like to avoid having to hardcode every event handler Maybe there's also a more straightforward way to achieve this instead of this approach? Cheers!
15 replies