Mathieu
Mathieu
Explore posts from servers
SSolidJS
Created by Mathieu on 11/8/2023 in #support
Use of `<Outlet />` vs `props.children` leads to duplicated code?
const EnsureAuthenticated: VoidComponent = () => {
return (
<Switch>
<Match when={/* ... */}>
<Loader />
</Match>
<Match when={/* ... */}>
/* ... */
</Match>
<Match when={/* ... */}>
<Outlet />
</Match>
</Switch>
);
};
const EnsureAuthenticated: VoidComponent = () => {
return (
<Switch>
<Match when={/* ... */}>
<Loader />
</Match>
<Match when={/* ... */}>
/* ... */
</Match>
<Match when={/* ... */}>
<Outlet />
</Match>
</Switch>
);
};
Take this component which renders <Outlet /> to render child routes. I want to reuse this component but not in a routing context, and I need to make use of props.children, as I want to render child components and not child routes. This leads me to having to duplicate the component code only because I need to use props.children instead of <Outlet />. Anyone struggled with this?
3 replies
SSolidJS
Created by Mathieu on 11/5/2023 in #support
Clicking browser's Back button from external site doesn't render the right state
The problem occurs only in production, not in localhost. When a user is redirected to an external site, then presses the brower's Back button, the SolidJS SPA is not rendering the right state. Example: Say the user wants to create an account via Google Oauth2, the user is redirected from the SolidJS SPA to the Google site to authenticate. If the user changes his/her mind, the user presses the Back button in the navigator. The SolidJS SPA is rendered but will show a spinner indefinitely, while nothing is loading, the component doesn't render the right state. It seems that the app renders the page just as it was right before being redirected to the external site (a spinner was displayed right after the Create Account button click and before the redirect), but if I log the state, there is no reason to show a spinner. It works as expected in localhost. Update: The document (the html page) and the JS asset seem not requested when going back from the external site (even though I can read logs from the JS code). In the Network tab I see only a request to: - favicon.ico (304) - example.com/foo.css (304) While in localhost the document is requested (200) It doesn't seem to be a problem related to the http caching though because the http response headers look okay: Cache-Control: public,max-age=0,must-revalidate (using Netlify) I think it's either something I miss to avoid the browser to use some in-memory cached resources (but unrelated to http-cache, the document isn't even fetched it seems), or a SolidJS router problem. Might have something to do with "bfcache"
2 replies
SSolidJS
Created by Mathieu on 10/19/2023 in #support
Can I avoid the getter while keeping the reactivity?
const [organization] = useSelectedOrganization();

const formatMoney = () => moneyFormatter(organization);
const [organization] = useSelectedOrganization();

const formatMoney = () => moneyFormatter(organization);
organization is reactive. I have a function returning me a money formatter (according to the organization's settings). The issue is in the code I have to use formatMoney like such:
formatMoney()(amount, currency)
formatMoney()(amount, currency)
Is it anyhow possible to keep reactivity on organization but to write:
formatMoney(amount, currency)
formatMoney(amount, currency)
4 replies
SSolidJS
Created by Mathieu on 10/16/2023 in #support
Issue with reactivity when using mergeProps
https://playground.solidjs.com/anonymous/61802a1d-b0c8-44d9-9675-e6e73cdf36d3 In this demo, I do not understand why the last log says:
[Select] props.selectedOption {id: '2', name: 'bar'}
I expected undefined and if I remove the mergeProps call, the selected option will be undefined as expected. (note that the code itself doesn't make much sense but I removed as much code as possible from the real app)
34 replies
SSolidJS
Created by Mathieu on 10/1/2023 in #support
Ref pointing to the wrong element
I have a component that uses a ref:
let bodyElement: HTMLDivElement;
// Somewhere in the TSX:
<div class={styles.body} ref={bodyElement!}>
let bodyElement: HTMLDivElement;
// Somewhere in the TSX:
<div class={styles.body} ref={bodyElement!}>
Let's say the component is called Foo. I have a parent component rendering Foo twice. The problem is that both refs bodyElement are pointing to the ref in the last Foo component. Inside Foo I log the refs:
onMount(() => {
console.log(bodyElement) // points to the last `bodyElement` in the last Foo
console.log(bodyElement.getBoundingClientRect())
});
onMount(() => {
console.log(bodyElement) // points to the last `bodyElement` in the last Foo
console.log(bodyElement.getBoundingClientRect())
});
and I notice that the logs are pointing to the same element, the last bodyElement (in the last Foo). I could not reproduce the problem in the playground.
5 replies
SSolidJS
Created by Mathieu on 9/3/2023 in #support
Variable initialized in `onMount` becomes `undefined`
let positionMenu: () => void;

onMount(() => {
positionMenu = getPositionMenuFun({ inputElement, styles });
console.log('positionMenu', positionMenu); // always outputs the function
});

createEffect(() => {
// ...
positionMenu(); // error: in one scenario `positionMenu` is undefined
});
let positionMenu: () => void;

onMount(() => {
positionMenu = getPositionMenuFun({ inputElement, styles });
console.log('positionMenu', positionMenu); // always outputs the function
});

createEffect(() => {
// ...
positionMenu(); // error: in one scenario `positionMenu` is undefined
});
I initialize a variable returning a function in the onMount callback, then call it in some effect. In one scenario positionMenu will be undefined. It is nowhere else in the code (only these occurrences of "positionMenu" as shown above). I noticed it's due to a clean up but I do not understand how the variable loses its value.
7 replies
SSolidJS
Created by Mathieu on 8/31/2023 in #support
How to initialize a store from another store?
I'd like to initialize a store (say store2) from another store (say store1). However if I change store2, I don't want it to affect store1. In the example below, I tried using unwrap but that didn't help: when a value in store2 changes, it affects store1. https://playground.solidjs.com/anonymous/b623bc24-5945-4676-a5cd-708584f6a2cc
9 replies
SSolidJS
Created by Mathieu on 8/25/2023 in #support
How to instruct a component to reset a state it holds?
I have a form looking like this (simplified code):
<Form>
<TextField value={store.foo} />
<Select value={store.bar} />
<TextArea value={store.baz} />
</Form>
<Form>
<TextField value={store.foo} />
<Select value={store.bar} />
<TextArea value={store.baz} />
</Form>
When submitting the form, errors can show up in red under each field. The errors are state (Signal) within the input components. How can I reset the error state (which are signals [error, setError] = createSignal('') in each input component) to empty (back to initial value '')? Note as to why I need this: the form is displayed in a dialog component, when the dialog closes and reopens, the form should reset to initial field values (this is easy as it is a store holding the values externally to the input components, so just need to reset the store to initial values) and not show any errors (this is where I struggle as the error is a signal within each component)
10 replies
SSolidJS
Created by Mathieu on 8/24/2023 in #support
Why is this store still reactive?
https://playground.solidjs.com/anonymous/5b3ceb29-ea8d-493d-a2fb-fd464b28ae2b I create a store in a createRoot block. I call dispose() right after creating the store. As seen in the demo, the store is still reactive even though I called dispose. Anyone knows why the store didn't lose reactivity even though it was created under a disposed root? What did dispose do? (note that I don't expect anything specific, I'm only trying to understand the behavior and mechanics)
2 replies
SSolidJS
Created by Mathieu on 8/23/2023 in #support
How to handle requests that need to be fetched later?
I use createResource to fetch data from the server and make it a reactive store. But on one page I have tabs. Say Users, Articles, Organizations tabs. For now, when a user navigates to this page, I send 3 requests to the server, and create 3 resources (create or get if already created previously).
const [users] = useUsersResource() // create the resource or return existing one
const [articles] = useArticlesResource()
const [organizations] = useOrganizationsResource()
const [users] = useUsersResource() // create the resource or return existing one
const [articles] = useArticlesResource()
const [organizations] = useOrganizationsResource()
But I would like to fetch e.g. the articles only when its tab Articles is clicked on. As (if I'm not wrong) I need the createResource call in the synchronous execution (and thus not in a callback), how could I achieve that? (note that my app is CSR only)
6 replies
SSolidJS
Created by Mathieu on 8/17/2023 in #support
What is wrong with this reactive select list?
https://playground.solidjs.com/anonymous/886c5e97-4d2e-427f-abf0-95df02ab0c71 The first select list in the playground works. But the second doesn't. If you click on an element and then another, there will be 2 selected elements. Any idea as to why is this happening for the second example but not the first?
5 replies
SSolidJS
Created by Mathieu on 8/16/2023 in #support
How to await on the Resource's promise?
Say users is a resource (from createResource). I would like to await for the underlying promise to complete. How could I acheive this?
const fetchUser = async (userId: string) => {
const [users] = useUsers(); // users is built with createResource
await users.???; // how to await the underlying promise?
return users().find(({ id }) => id === userId);
};
const fetchUser = async (userId: string) => {
const [users] = useUsers(); // users is built with createResource
await users.???; // how to await the underlying promise?
return users().find(({ id }) => id === userId);
};
15 replies
SSolidJS
Created by Mathieu on 7/7/2023 in #support
Why is this Resource fetcher called 2 times?
https://playground.solidjs.com/anonymous/347f9b68-3bae-4021-8276-00ac67404618 This log is displayed two times:
"---> why is second resource fetcher called 2 times?"
Any idea as to why?
89 replies
SSolidJS
Created by Mathieu on 7/1/2023 in #support
Make a Resource depend on another Resource
I would like to have a resource depend (awaiting) on another, like so:
const [resource2] =
createResource(
async () => {
await resource1.promise; // no such property exists
return fetch();
});
const [resource2] =
createResource(
async () => {
await resource1.promise; // no such property exists
return fetch();
});
However I don't have access to the promise in the return of the resource: https://docs.solidjs.com/references/api-reference/basic-reactivity/createResource See ResourceReturn doesn't expose the promise/fetcher.
6 replies
SSolidJS
Created by Mathieu on 6/25/2023 in #support
fetch in createEffect?
When a set of conditions are satisfied on some state, I want to execute an http request to the server. I'd have something like:
createEffect(() => {
if (state() && anotherState()) {
andAnotherState();
// execute http request
andYetAnotherState();
}
});
createEffect(() => {
if (state() && anotherState()) {
andAnotherState();
// execute http request
andYetAnotherState();
}
});
Is it okay to initiate http request from createEffect? Is there anything to be aware of? I guess I don't need to use async/await? (i.e. I don't need to write createEffect(async () => // ...) as the synchronous execution shouldn't be paused?)
8 replies
SSolidJS
Created by Mathieu on 6/9/2023 in #support
Html elements have no space in between them
Say in a component I render the following:
<span>foo</span>
<A href="/url">link</A>
<span>foo</span>
<A href="/url">link</A>
I noticed that it will result in the html being <span>foo</span><a href="/url">link</a> without any space in between, resulting in foolink instead of foo link on the screen. How should I handle this issue?
3 replies
SSolidJS
Created by Mathieu on 6/6/2023 in #support
Solid Router and losing Contexts
When navigating to a route, I noticed I lose all the context values. I have to wrap the component (that needs to rendered for the route) again by all the context providers, and for every route. Is this normal? It seems awkward. (of course I can create some generic component that wraps the component to render for that route with all the context providers again, but is it normal in the first place that I lose the contexts? If so, how do you approach this?)
<Route
path={translate('uri_select_login_auth_method')}
element={
<BarContextProvider>
<FooContextProvider>
<Content><AuthenticationMethodSelector mode="login" /></Content>
</FooContextProvider>
</BarContextProvider>
}
/>
<Route
path={translate('uri_select_login_auth_method')}
element={
<BarContextProvider>
<FooContextProvider>
<Content><AuthenticationMethodSelector mode="login" /></Content>
</FooContextProvider>
</BarContextProvider>
}
/>
28 replies
SSolidJS
Created by Mathieu on 6/5/2023 in #support
Effects not running after a unhandled promise rejection event
When an unhandled error event occurs (e.g. by throwing new Error()), the ErrorBoundary is catching the error. When an unhandled promise rejection occurs, the UI/JSX is being updated, I display the state of the resource in the JSX, and it switches from pending to errored, but the createEffect functions are not running:
createEffect(() => {
console.log('userResource.state', userResource.state);
});
createEffect(() => {
console.log('userResource.state', userResource.state);
});
When displaying {userResource.state} from the JSX, it prints pending and then updates to errored because there was a promise rejection. It reacts. However the createEffect above only logs pending once and will not log errored, while the JSX did react/get updated.
const EnsureAuthenticated: VoidComponent = () => {
const [currentUser] = useCurrentUser();

createEffect(() => {
// doesn't react (logs only pending once)
console.log('currentUser.state', currentUser.state);
});

return (
// reacts (displays pending then errored)
<>{currentUser.state}</>
);
};
const EnsureAuthenticated: VoidComponent = () => {
const [currentUser] = useCurrentUser();

createEffect(() => {
// doesn't react (logs only pending once)
console.log('currentUser.state', currentUser.state);
});

return (
// reacts (displays pending then errored)
<>{currentUser.state}</>
);
};
49 replies
SSolidJS
Created by Mathieu on 5/30/2023 in #support
How to throw an Error on an unknown route?
I define the content for each route like so:
return (
<Routes>
<Route path={'/foo'} element={<Foo />} />
<Route path={'/bar'} element={<Bar />} />
return (
<Routes>
<Route path={'/foo'} element={<Foo />} />
<Route path={'/bar'} element={<Bar />} />
If there is an unknown route like /baz, no component will be rendered (leading to a blank page in my case). However I would like to throw an Error if that happens. What would be the best way to achieve this?
3 replies
SSolidJS
Created by Mathieu on 5/28/2023 in #support
createResource swallows error?
I noticed errors get swallowed when I use createResource. Here is some simplified example code:
window.addEventListener('unhandledrejection', (e) => console.error(e));
window.addEventListener('error', (e) => console.error(e));

function getCurrentUserResource() {
const [userData] =
createResource<any>(
async () => {
console.log('hello!') // logs
throw 'error'; // swallowed
}
);
return userData;
}

getCurrentUserResource();
window.addEventListener('unhandledrejection', (e) => console.error(e));
window.addEventListener('error', (e) => console.error(e));

function getCurrentUserResource() {
const [userData] =
createResource<any>(
async () => {
console.log('hello!') // logs
throw 'error'; // swallowed
}
);
return userData;
}

getCurrentUserResource();
The error is not logged in the console
12 replies