Mr Void
Mr Void
Explore posts from servers
SSolidJS
Created by Mr Void on 9/29/2024 in #support
disable untrack when param changes
is it possible to, again, track an untracked signal when useParams parameters changes. I have a component that retrieves some data from the store based on a URL parameter.
const params = useParams()
const [currentNote, setCurrentNote] = createSignal<Note>()

createEffect(async () => {
// <data from store depending on params.note_id>
setCurrentNote(...)
})

<Editor
// untracking to avoid bug in editor whenever data is autosaved
// however, this needs to be updated when URL param changes
data={untrack(() => currentNote()?.data) || undefined}
/>
const params = useParams()
const [currentNote, setCurrentNote] = createSignal<Note>()

createEffect(async () => {
// <data from store depending on params.note_id>
setCurrentNote(...)
})

<Editor
// untracking to avoid bug in editor whenever data is autosaved
// however, this needs to be updated when URL param changes
data={untrack(() => currentNote()?.data) || undefined}
/>
5 replies
SSolidJS
Created by Mr Void on 9/26/2024 in #support
load custom css after a package is loaded
perhaps this doesn't belong in this forum, I apoloize I'm trying to override the variables from a css file that belongs to a package, but can't seem to do that because what I write in index.css file gets overriden by the package file's css which loads later. Is there a way for me to import an additional css file after the package is loaded?
4 replies
SSolidJS
Created by Mr Void on 9/16/2024 in #support
Prevent re-rendering many components when object in store-array is updated
I have a grid view where multiple card components are rendered. The issue is that all cards are re-rendered when one of the cards' data is updated in the store. Is there a way to prevent re-rendering everything when one object in the array is modified? This is how the card is modified:
updateCard(flashcard: Flashcard) {
setState("flashcards", "collections", (collections: FlashcardCollection[]) => {
const tempCollections = [...collections]

return tempCollections.map((collection) => {
const tempCollection = {...collection}
const cards = [...tempCollection.flashcards]

tempCollection.flashcards = cards.map((currentCard) => {
if (currentCard.id !== flashcard.id) {
return currentCard
}

return Object.assign({}, currentCard, flashcard)
})

return tempCollection
})
})
}
updateCard(flashcard: Flashcard) {
setState("flashcards", "collections", (collections: FlashcardCollection[]) => {
const tempCollections = [...collections]

return tempCollections.map((collection) => {
const tempCollection = {...collection}
const cards = [...tempCollection.flashcards]

tempCollection.flashcards = cards.map((currentCard) => {
if (currentCard.id !== flashcard.id) {
return currentCard
}

return Object.assign({}, currentCard, flashcard)
})

return tempCollection
})
})
}
and here is how i load & filter cards
const currentCollection = createAsync<FlashcardCollection>(async (prev) => {
const collection: FlashcardCollection
= store.flashcards.collections.find(
(collection) => collection.id === params.collection_id
)

return unwrap(collection)
})

const filteredCards = createMemo(() => {
const coll = currentCollection() as FlashcardCollection
return coll.flashcards.filter(card => /* filtration condition here */)
})
const currentCollection = createAsync<FlashcardCollection>(async (prev) => {
const collection: FlashcardCollection
= store.flashcards.collections.find(
(collection) => collection.id === params.collection_id
)

return unwrap(collection)
})

const filteredCards = createMemo(() => {
const coll = currentCollection() as FlashcardCollection
return coll.flashcards.filter(card => /* filtration condition here */)
})
<For each={filteredCards()}>
{(flashcard) => <Card data={flashcard} /> }
</For>
<For each={filteredCards()}>
{(flashcard) => <Card data={flashcard} /> }
</For>
17 replies
SSolidJS
Created by Mr Void on 9/16/2024 in #support
Reset signals when prop value changes
How can I reset the showFront state of Card when Card's props.data changes?
type CardProps = {
data: Card
}

const Card = (props: CardProps) => {
const [showFront, setShowFront] = createSignal<boolean>(true)
// ...
}
type CardProps = {
data: Card
}

const Card = (props: CardProps) => {
const [showFront, setShowFront] = createSignal<boolean>(true)
// ...
}
return (
<Container>
<Card data={currentCard()} />
<!-- buttons to navigate between cards -->
</Container>
)
return (
<Container>
<Card data={currentCard()} />
<!-- buttons to navigate between cards -->
</Container>
)
8 replies
SSolidJS
Created by Mr Void on 6/15/2024 in #support
nested router, root leads to 404
I wish have the waterfall effect on rendering parent -> child components but I'm facing an issue with the following configuration. When I navigate to /flashcards I get redirected to Page404.
<Router>
<Route path="/" component={allowAuthenticated(AppContainer)}>
{/* other route configurations here */}

<Route path="/flashcards" component={Flashcards}>
<Route path="/" component={FlashcardsOverview}>
<Route path="collection/:collection_id" component={FlashcardCollectionsView} />
</Route>
</Route>
</Route>

<Route path="*404" component={Page404} />
</Router>
<Router>
<Route path="/" component={allowAuthenticated(AppContainer)}>
{/* other route configurations here */}

<Route path="/flashcards" component={Flashcards}>
<Route path="/" component={FlashcardsOverview}>
<Route path="collection/:collection_id" component={FlashcardCollectionsView} />
</Route>
</Route>
</Route>

<Route path="*404" component={Page404} />
</Router>
I've tried doing the same as the docs: parent is a wrapper component and contains sub-components including it's root:
<Route path="/" component={ ... }>
<Route path="layer1" component={ ... }>
<Route path="layer2" component={ ... }/>
</Route>
</Route>
<Route path="/" component={ ... }>
<Route path="layer1" component={ ... }>
<Route path="layer2" component={ ... }/>
</Route>
</Route>
In my case, Flashcards is the wrapper component
const Flashcards = (props: ParentProps) => {
return (<>{props.children}</>)
}
const Flashcards = (props: ParentProps) => {
return (<>{props.children}</>)
}
FlashcardsOverview is the component which should render when navigating to /flashcards and FlashcardCollectionsView should render as a child component of FlashcardsOverview when navigating to /flashcards/collection/:id How can I achieve this? Why does this configuration cause 404 ?
5 replies
SSolidJS
Created by Mr Void on 2/19/2024 in #support
solid-router | return Navigate as component
Is there any way to return <Navigate href="/auth/login" /> as a component rather than an element? On version [email protected] I was able to return an element for a route, however the new version 0.12 requires a component instead.
const ProtectedRoutes = () => {
const store: StoreState = useStore()

const allowAuthenticated = (accept: Component): Component => {
if (store.user.isAuthenticated) {
return accept
}

return <Navigate href="/auth/login" /> // Need to return this as a component
}

const denyAuthenticated = (accept: Component): Component => {
if (!store.user.isAuthenticated) {
return accept
}

return <Navigate href="/" /> // Need to return this as a component
}

return (
<Router root={App}>
<Route path="/" component={allowAuthenticated(AppContainer)}>
...
</Router>
)
...
}
const ProtectedRoutes = () => {
const store: StoreState = useStore()

const allowAuthenticated = (accept: Component): Component => {
if (store.user.isAuthenticated) {
return accept
}

return <Navigate href="/auth/login" /> // Need to return this as a component
}

const denyAuthenticated = (accept: Component): Component => {
if (!store.user.isAuthenticated) {
return accept
}

return <Navigate href="/" /> // Need to return this as a component
}

return (
<Router root={App}>
<Route path="/" component={allowAuthenticated(AppContainer)}>
...
</Router>
)
...
}
2 replies
SSolidJS
Created by Mr Void on 2/19/2024 in #support
Anchor with target="_blank" leading to app's URL
No description
18 replies
SSolidJS
Created by Mr Void on 1/7/2024 in #support
Store item = undefined, causes typescript error
items[item.id] = undefined
items[item.id] = undefined
throws:
Type 'undefined' is not assignable to type '{ ...<item props> }'.ts(2322)
Type 'undefined' is not assignable to type '{ ...<item props> }'.ts(2322)
How to deal with this? I wish to avoid having undefined as a type: items: { [key: string]: Item | undefined }
5 replies
SSolidJS
Created by Mr Void on 1/6/2024 in #support
How to keep store in sync with supabase's multitab session?
A logged in user's data is stored in store:
const initialState = {
id: null,
username: null,
display_name: null,
about_me: null,
avatar_url: "",

loading: true,
isAuthenticated: false,
...
}
const initialState = {
id: null,
username: null,
display_name: null,
about_me: null,
avatar_url: "",

loading: true,
isAuthenticated: false,
...
}
When a user signs out within the app, store is reset to default values. So far it works as expected. However, if the logged in user is viewing the app on multiple tabs and logs out on one of them then rest of the tabs remain active because store is not synced between tabs. I asked this on Supabase's forum and got the following response:
Me: I have noticed that when a session is active on one tab, it doesn't refresh on other tabs. After some searching, I came across this PR: https://github.com/supabase/gotrue-js/pull/566 It mentions that storageKey should be used for the channel's name. What is- and where is the storageKey obtained from?
Moderator: storageKey is used to separate the supabase clients so they don't interact. If you don't use it in createClient options then all of the tabs should be in sync.
Me: Tabs are in sync how? For example, I store the logged in user's data in a redux- like store. Should I subscribe to some type of auth event in order to know if a user is logged out?
Moderator: Supabase-js is set up to keep the local storage in sync for multiple tabs. I don't know what redux-like storage is in the context here. I don't think you said what your environment is. But on simple javascript browser Supabase uses local storage to keep the tabs in sync (or it is supposed to). If you are doing something with sessions on your own then you would need to describe that method and see if someone has ideas.
I'm not quite sure how to proceed here. I inspected the local-storage and found that an access key is stored there: sb-[app id]-auth-token: { access_token: ... } Is there a way to listen to this change? How can I keep the tabs in sync, with store in mind?
3 replies
SSolidJS
Created by Mr Void on 12/28/2023 in #support
component doesnt react to changes in state
I've got a component that has a state collaborators which holds an array of objects. The problem is that when this state is modified, through setCollaborators function, the component does not update for the new value. why is this happenin, and how can I work around this issue?
const CollectionsView = () => {
const store: StoreState = useStore()
const params = useParams()

const [currentCollection, setCurrentCollection] = createSignal<Collection>()
const [currentCollaborators, setcurrentCollaborators] = createSignal<UserSummary[]>([])


createEffect(() => {
console.log(store.cards.collections)

let collection: Collection | undefined
= store.cards.collections.find(
(collection) => collection.id === params.collection_id
)

if (collection === undefined) {
collection = store.cards.sharedCollections.find(
(collection) => collection.id === params.collection_id
)

if (collection === undefined) {
navigate("/fcards")
return
}
}

batch(() => {
setCurrentCollection(collection)
setcurrentCollaborators(collection!.collaborators)
// this shows the correct value:
console.log("collaborators: ", currentCollaborators())
})
})

return (
// ...
// the following does not re-render with new changes
<For each={currentCollaborators()!}>
{(collaborator) => <div>{collaborator.display_name}</div>}
</For>
)
const CollectionsView = () => {
const store: StoreState = useStore()
const params = useParams()

const [currentCollection, setCurrentCollection] = createSignal<Collection>()
const [currentCollaborators, setcurrentCollaborators] = createSignal<UserSummary[]>([])


createEffect(() => {
console.log(store.cards.collections)

let collection: Collection | undefined
= store.cards.collections.find(
(collection) => collection.id === params.collection_id
)

if (collection === undefined) {
collection = store.cards.sharedCollections.find(
(collection) => collection.id === params.collection_id
)

if (collection === undefined) {
navigate("/fcards")
return
}
}

batch(() => {
setCurrentCollection(collection)
setcurrentCollaborators(collection!.collaborators)
// this shows the correct value:
console.log("collaborators: ", currentCollaborators())
})
})

return (
// ...
// the following does not re-render with new changes
<For each={currentCollaborators()!}>
{(collaborator) => <div>{collaborator.display_name}</div>}
</For>
)
49 replies
SSolidJS
Created by Mr Void on 12/18/2023 in #support
setState variable as path doesn't work
The following works
setState("items", "collections", (collections: ItemCollection[]) =>
[...collections].filter((collection) =>
collection.id !== collection_id
)
)
setState("items", "collections", (collections: ItemCollection[]) =>
[...collections].filter((collection) =>
collection.id !== collection_id
)
)
However, this doesn't work, why? path is always one of the possible keys inside items object.
setState("items", path, (collections: ItemCollection[]) =>
[...collections].filter((collection) =>
collection.id !== collection_id
)
)
setState("items", path, (collections: ItemCollection[]) =>
[...collections].filter((collection) =>
collection.id !== collection_id
)
)
ts error:
Argument of type 'string' is not assignable to parameter of type 'Part<ItemStore, keyof ItemStore>'. ts(2345)
Argument of type 'string' is not assignable to parameter of type 'Part<ItemStore, keyof ItemStore>'. ts(2345)
4 replies
SSolidJS
Created by Mr Void on 12/15/2023 in #support
Is there any way of caching an image loaded from a url?
I've got images stored on supabase's storage and the first time a component renders, it creates a signedUrl and uses that url within the image element. However, this happens each time the component re-renders. I wish to avoid the loading time by caching the image itself, not the link. Is this possible? If so how? Could the image data be cached in solid store?
1 replies
SSolidJS
Created by Mr Void on 12/14/2023 in #support
accessing store multiple time, in batch() causes infinite loop
createEffect(() => {
batch(async () => {
for (const card of collection.cards) {
// some async call ...
const tempCard = {...card}
// updating properties
store.cards.dispatch.updateCard(tempCard)
}
// ...
})
})
createEffect(() => {
batch(async () => {
for (const card of collection.cards) {
// some async call ...
const tempCard = {...card}
// updating properties
store.cards.dispatch.updateCard(tempCard)
}
// ...
})
})
Calling store's function within the loop causes infinite rendering. The batch function is inside createEffect. How could I avoid an infinite loop, while still updating the objects 1 by 1 ?
8 replies
SSolidJS
Created by Mr Void on 12/9/2023 in #support
Unable to edit data in store ( Solved )
No description
2 replies
SSolidJS
Created by Mr Void on 11/7/2023 in #support
Warning when modal uses state
I have created a context provider ModalProvider that is meant to display a modal whenever it's visible state is true. This container is displayed on top of any other element that exists within the App. It worked well, until I created a state within the modal itself - at which point it began throwing the following warning:
computations created outside a `createRoot` or `render` will never be disposed
computations created outside a `createRoot` or `render` will never be disposed
Why does this happen when myModal component is using a state? ( this is displayed in the ModalProvider ) https://stackblitz.com/edit/solidjs-templates-bnxz3s?file=src%2FApp.tsx
5 replies
SSolidJS
Created by Mr Void on 10/31/2023 in #support
Why does `Outlet` not work when using `element` instead of `component` in the configuration?
Wrapper / container
const MainContainer = () => (
<div class="flex flex-row min-h-screen">
<Outlet />
</div>
)
const MainContainer = () => (
<div class="flex flex-row min-h-screen">
<Outlet />
</div>
)
This works:
const MainContainer = lazy(() => import("../mainContainer"))

const Dashboard = lazy(() => import("../../pages/dashboard"))

const Routes = useRoutes([
{
path: "/",
component: MainContainer,
children: [
{ path: "/dashboard", component: Dashboard }
]
}
])
const MainContainer = lazy(() => import("../mainContainer"))

const Dashboard = lazy(() => import("../../pages/dashboard"))

const Routes = useRoutes([
{
path: "/",
component: MainContainer,
children: [
{ path: "/dashboard", component: Dashboard }
]
}
])
This doesn't work:
const MainContainer = lazy(() => import("../mainContainer"))

const Dashboard = lazy(() => import("../../pages/dashboard"))

const Routes = useRoutes([
{
path: "/",
element: <MainContainer />,
children: [
{ path: "/dashboard", element: <Dashboard /> },
]
}
])
const MainContainer = lazy(() => import("../mainContainer"))

const Dashboard = lazy(() => import("../../pages/dashboard"))

const Routes = useRoutes([
{
path: "/",
element: <MainContainer />,
children: [
{ path: "/dashboard", element: <Dashboard /> },
]
}
])
17 replies
SSolidJS
Created by Mr Void on 10/31/2023 in #support
Custom ProtectedRoutes component does not render elements on URL match
I've created a custom component ProtectedRoutes which is rendered within App.tsx. The purpose is to check the URL that the user is viewing, allow or deny based on store.user.isAuthenticated variable. There are also two sub-components for ProtectedRoutes. One is AllowAuthenticated:
import { JSX, createEffect } from "solid-js";
import { StoreState, useStore } from "../../store";
import { Navigate } from "@solidjs/router";

type ProtectedRouteProps = {
accept: JSX.Element
}

const AllowAuthenticated = (props: ProtectedRouteProps) => {
// ...

const store: StoreState = useStore()
return (
store.user.isAuthenticated === true ?
props.accept
:
<Navigate href={'/login'} />
)
}

export default AllowAuthenticated;
import { JSX, createEffect } from "solid-js";
import { StoreState, useStore } from "../../store";
import { Navigate } from "@solidjs/router";

type ProtectedRouteProps = {
accept: JSX.Element
}

const AllowAuthenticated = (props: ProtectedRouteProps) => {
// ...

const store: StoreState = useStore()
return (
store.user.isAuthenticated === true ?
props.accept
:
<Navigate href={'/login'} />
)
}

export default AllowAuthenticated;
And similarly, the other is DenyAuthenticated which redirects the user to a default URL for authenticated users. Here's what the ProtectedRoutes component looks like:
const ProtectedRoutes = () => {

createEffect(() => {
console.log('> ProtectedRoutes')
})

const Routes = useRoutes([
{
path: "/",
element: <AllowAuthenticated accept={<MainContainer />} />,
children: [
{ path: ["/", "dashboard"], component: Dashboard },
{ path: "profile", component: Profile }
]
},
{ path: "/login", element: <DenyAuthenticated accept={<Login />} /> },
{ path: "/register", element: <DenyAuthenticated accept={<Register />} /> }
])

return <Routes />
}
const ProtectedRoutes = () => {

createEffect(() => {
console.log('> ProtectedRoutes')
})

const Routes = useRoutes([
{
path: "/",
element: <AllowAuthenticated accept={<MainContainer />} />,
children: [
{ path: ["/", "dashboard"], component: Dashboard },
{ path: "profile", component: Profile }
]
},
{ path: "/login", element: <DenyAuthenticated accept={<Login />} /> },
{ path: "/register", element: <DenyAuthenticated accept={<Register />} /> }
])

return <Routes />
}
For some reason, when URL is / or any of the children paths /dashboard, /profile - their contents are not rendered on the page. However, not using Allow/DenyAuthenticated elements, then the pages are rendered as expected. What might be the issue here?
here is a minimal version: https://stackblitz.com/edit/solidjs-templates-gkkfyr?file=src%2FApp.tsx
1 replies
SSolidJS
Created by Mr Void on 10/29/2023 in #support
setState - typescript : Argument of type 'string' is not assignable to parameter of type 'never'
Receiving the following error:
Argument of type 'string' is not assignable to parameter of type 'never'
Argument of type 'string' is not assignable to parameter of type 'never'
for the line:
setState("user", "id", () => data.id);
setState("user", "id", () => data.id);
Context:
function createUserStoreDispatch(setState: SetStoreFunction<StoreState>): UserStoreDispatch {
return {
login(data: loginData) {
batch(() => {
setState("user", "id", () => data.id);
// ... ^ TYPESCRIPT ERROR
});
}
}
}
function createUserStoreDispatch(setState: SetStoreFunction<StoreState>): UserStoreDispatch {
return {
login(data: loginData) {
batch(() => {
setState("user", "id", () => data.id);
// ... ^ TYPESCRIPT ERROR
});
}
}
}
export type StoreState = {
user: UserStore
} | object

export default function StoreProvider(props: any) {
const [state, setState]: [Store<StoreState>, SetStoreFunction<StoreState>] = createStore<StoreState>({});
export type StoreState = {
user: UserStore
} | object

export default function StoreProvider(props: any) {
const [state, setState]: [Store<StoreState>, SetStoreFunction<StoreState>] = createStore<StoreState>({});
Why is the type "never" ?
2 replies
SSolidJS
Created by Mr Void on 9/23/2023 in #support
Is the following a "clean" way of handling modals?
I'm trying to figure out a "clean", "best-practice" way of handling modals in an app. Have been experimenting in the following playground: https://playground.solidjs.com/anonymous/d3e943ee-e2fd-48e8-87ce-76d271f72b23 Please take a look and let me know if you have any feedback, or what your thoughts are regarding this
3 replies
SSolidJS
Created by Mr Void on 6/9/2023 in #support
child-components not updating when parent state is modified.
Paragraph component: https://pastebin.com/raw/Y9tM6qgN Word component: https://pastebin.com/raw/zR6JCYbD Description The Paragraph component keeps track of Word components' data within a signal. It contains toggleWordMark function which is passed to each Word component as a callback function. Each Word, when clicked, calls toggleWordMark and its data is updated within the Paragraph's words signal. Problem The word components are not re-rendered when the Paragraph state is modified.
14 replies