hannus
hannus
SSolidJS
Created by hannus on 11/8/2024 in #support
can I handle a group of useSubmisson?
if an action is still pending (like during a synchronization) and another modification occurs that triggers a second update, how should useSubmission handle this? Would it be better to avoid new action submissions while an update is pending, or is there a pattern you would recommend for handling overlapping updates gracefully? thanks
8 replies
SSolidJS
Created by hannus on 8/26/2024 in #support
Modifying Signals Returned by createAsync in SolidJS: Best Practices and Alternatives
In SolidJS (using the SolidStart framework), how can I modify the signal returned by createAsync? For example, in a scenario where I use createAsync to fetch data from an API and load it into an editor or textarea, then after making modifications, I want to save the updates via an Action by calling another API. The parameter passed to the Action would be the modified data based on what was initially fetched by createAsync. I checked the documentation but couldn’t find a way to modify the signal from createAsync. So I came up with two possible solutions: 1. Use createResource; 2. Create another signal B, then use onMount to set signal B based on the final value of the signal from createAsync. To ensure that signal B is only set after the createAsync value is resolved, the current component would be wrapped in a Suspense component, ensuring other parts are rendered only after the async data is loaded. Is my approach correct? Additionally, the documentation mentions that createAsync is a lightweight version of createResource and will become a primitive in Solid 2.0. Does this mean that createAsync is more recommended for use? thanks
4 replies
SSolidJS
Created by hannus on 8/22/2024 in #support
How can I make createEffect in SolidJS execute only when the dependency variable changes, and not wh
For example:
const [value, setValue] = createSignal<string>("")
createEffect(() => { localStorage.setItem("value", value()) })
const [value, setValue] = createSignal<string>("")
createEffect(() => { localStorage.setItem("value", value()) })
I want to save the value to localStorage only after modifying the value, but do nothing when it is initially created with the value "". I remember that in previous documentation, createEffect wouldn’t execute if the dependency variable was false or undefined. But it seems that this behavior has changed now.
18 replies
SSolidJS
Created by hannus on 7/20/2024 in #support
Confusion about Preload mechanism
I am confused about the preload mechanism. According to my understanding, adding an asynchronous function wrapped by a cache in preload initiates data fetching when the route is accessed, ensuring the data is ready when the page starts rendering. Observing the console, this indeed happens. When the function is called within the route component, the data should already be prepared. Even if an asynchronous function calls this function, it should immediately return the data. However, my observation is different; there is still an asynchronous process to re-fetch the data. The sample code is as follows:
// function in the preload()
export async function handleUser(): Promise<void> {
"use server";
const userinfo = await fetchUserInfo("http://localhost:8000/getuserinfo/");
console.log("userinfo", userinfo);
if (userinfo === undefined) {
throw redirect("/login")
}
}

export const handleUserCache = cache(handleUser, "handleUser");

// in route component file

export const route = {
preload() {
handleUserCache();
}
} satisfies RouteDefinition;

export default function Auth() {
console.log("start auth page render")
const userinfo = createAsync(() => handleUserCache());
console.log("after async function")

return ....
// function in the preload()
export async function handleUser(): Promise<void> {
"use server";
const userinfo = await fetchUserInfo("http://localhost:8000/getuserinfo/");
console.log("userinfo", userinfo);
if (userinfo === undefined) {
throw redirect("/login")
}
}

export const handleUserCache = cache(handleUser, "handleUser");

// in route component file

export const route = {
preload() {
handleUserCache();
}
} satisfies RouteDefinition;

export default function Auth() {
console.log("start auth page render")
const userinfo = createAsync(() => handleUserCache());
console.log("after async function")

return ....
8 replies
SSolidJS
Created by hannus on 7/19/2024 in #support
Can I Preload Data in Non-Route Components?
In SolidStart, I can use preload to fetch data when a route is loaded, ensuring that the data is ready by the time the route component is rendered. This is particularly useful for scenarios such as route guards and data display. However, if there are other components within the pages corresponding to these routes that also need data, can preload be used for them as well? For example, every page includes a Nav component, as shown in the following code:
// app.tsx
<Router
root={(props) => (
<>
<Nav />
<Suspense>{props.children}</Suspense>
</>
)}
>
<FileRoutes />
</Router>
// app.tsx
<Router
root={(props) => (
<>
<Nav />
<Suspense>{props.children}</Suspense>
</>
)}
>
<FileRoutes />
</Router>
The Nav component is not inside the routes folder, and using preload does not expose it correctly to the Router. Therefore, when the Nav component needs to render information based on data (e.g., displaying the username if the user is logged in or a login button if not), the component experiences a sudden change due to asynchronous loading. Is there a way to preload data for components that are not inside the routes folder? For example, if we could preload data for components like Nav or Sidebar, it would prevent sudden changes in their content. thanks
1 replies
SSolidJS
Created by hannus on 7/16/2024 in #support
is it necessary to mark "use server" for useSession
"use server" means executing only on the server. So, is it necessary to mark "use server" for useSession of h3? If marked, is there a risk of execution order issues? In the example (with-auth), I did not see the "use server" marker. However, in one of my experimental projects, if I don’t add "use server", the build fails. After adding "use server" and successfully building, every time I refresh the page, the previously initialized h3 session with data gets cleared. I suspect that use server is causing a delay in the execution time of useSession. Here is the code where I use useSession:
export async function getSession(): Promise<ReturnType<typeof useSession>> {
"use server";
return useSession({
password: process.env.SESSION_SECRET ?? "secretsecretsecretsecretsecretsecretsecretsecretsecretsecret",
});
}
export async function getSession(): Promise<ReturnType<typeof useSession>> {
"use server";
return useSession({
password: process.env.SESSION_SECRET ?? "secretsecretsecretsecretsecretsecretsecretsecretsecretsecret",
});
}
thanks a lot
8 replies
SSolidJS
Created by hannus on 6/22/2024 in #support
Proper Usage of load() for Authentication and Redirection in Solid-Start
Scenario: When a user tries to access a route that requires authentication, they should be redirected to the login route. After logging in, the user should be redirected back to the originally requested route. To achieve this, I created a function getUserWithQueryPara. This function checks if a session token is saved. If a token exists, it fetches the user information based on the token; if not, it redirects to the login component. To ensure the user is redirected back to the originally requested route after authentication, a query parameter is added to the login route. Here is the getUserWithQueryPara function:
export const getUserWithQueryPara = cache(async (query?: string) => {
"use server";
const session = await getSession();
const token = session.data.token;
if (token === undefined) throw redirect(`/login?from=${query}`);
const userinfo = await fetchUserPublicWeb(token);
return userinfo;
}, "userinfo");
export const getUserWithQueryPara = cache(async (query?: string) => {
"use server";
const session = await getSession();
const token = session.data.token;
if (token === undefined) throw redirect(`/login?from=${query}`);
const userinfo = await fetchUserPublicWeb(token);
return userinfo;
}, "userinfo");
In the route that requires authentication, to improve performance, I attempted to use load() to pre-load getUserWithQueryPara. In the component, I use createAsync to obtain the result of getUserWithQueryPara. Considering that the getUserWithQueryPara function needs the pathname parameter to handle redirection for unauthenticated users, I added const pathname = useLocation().pathname in both the load() function and before creating createAsync in the component. This is to ensure consistency between pre-loading and in-component loading. Is my approach correct? Any suggestions or improvements would be appreciated. Thank you. Below is the code snippet for the component:
export const route = {
load() {
const pathname = useLocation().pathname;
void getUserWithQueryPara(pathname);
},
} satisfies RouteDefinition;
export default function Create() {
const pathname = useLocation().pathname;
const userinfo = createAsync(() => getUserWithQueryPara(pathname), {
deferStream: true,
});
return (...)
export const route = {
load() {
const pathname = useLocation().pathname;
void getUserWithQueryPara(pathname);
},
} satisfies RouteDefinition;
export default function Create() {
const pathname = useLocation().pathname;
const userinfo = createAsync(() => getUserWithQueryPara(pathname), {
deferStream: true,
});
return (...)
18 replies
SSolidJS
Created by hannus on 4/7/2024 in #support
how to edit html attribute?
In the v1.0rc of solidstart, the Html tag generated in the entry-server.jsx. Is there a method to change the html attribute such as change dark theme to light theme in other components? If I created a signal to control the theme in entry-server.jsx, I have to use context to share the signal. Is it a proper way to wrap StartServer component into a Context in entry-server.jsx? I think it is a little strange. Is there another method? thanks a lot
4 replies
SSolidJS
Created by hannus on 4/5/2024 in #support
how to deal with flashes of unstyled content
the version of soild-start is v1.0 RC. It shows a unstyled content a while when I refresh the page. In the example of with-tailwindcss, it has the memont of unstyled as well. Is there a solution to solve ? On other hand, Have I made some mistake during render? thanks a lot
3 replies
SSolidJS
Created by hannus on 3/27/2024 in #support
[solved]Issue with Solid Start MDX Project: 404 Error for New Page
No description
21 replies
SSolidJS
Created by hannus on 2/17/2024 in #support
is Index of Store that is array Signal?
I created an array containing several objects based on createStore. When I iterate through this array using a For component and access each object, I don’t need to use a function call to retrieve specific data. This behavior aligns with the documentation. However, when I want to perform actions based on the array’s index (such as deleting the current object), I need to use a function call to correctly obtain the index value. Here’s the code snippet:
<For each={items}>
{(item, index) => (
<div className="container">
<div className="level px-6 is-mobile has-shadow">
<div className="level-left">
<p>{item.name}-{index}</p>
</div>
<div className="level-right">
<button
className="button is-danger is-small"
onClick={() => handleDelete(index())}
>
Delete
</button>
</div>
</div>
<hr></hr>
</div>
)}
</For>
<For each={items}>
{(item, index) => (
<div className="container">
<div className="level px-6 is-mobile has-shadow">
<div className="level-left">
<p>{item.name}-{index}</p>
</div>
<div className="level-right">
<button
className="button is-danger is-small"
onClick={() => handleDelete(index())}
>
Delete
</button>
</div>
</div>
<hr></hr>
</div>
)}
</For>
is the index a signal? Why I have to access the value via function call in the event of onClick? However, access the value as a property works well in the JSX. Thanks a lot
15 replies
SSolidJS
Created by hannus on 2/16/2024 in #support
some confusion regarding authentication when accessing third-party APIs in SolidStart.
I have some confusion regarding authentication when accessing third-party APIs in SolidStart. Here’s the scenario: 1. I want to use Server-Side Rendering (SSR), so I chose SolidStart. 2. When accessing a third-party API, bearer authentication is required. 3. In SolidStart, both the client and server may make API requests. 4. For server-side requests, I store the token in a cookie attached to the HTTP request. The server then extracts the token and makes the third-party API request. This approach seems feasible and necessary (since only cookies can consistently carry the token with each request). 5. After rendering, the client-side may also need to access authenticated APIs. In this case, both cookies and localStorage can be used. However, localStorage is more convenient due to the security setting of httpOnly for cookies. 6. Handling client-side API requests requires same logic. My questions are: 1. Should I explicitly differentiate between server-side rendering (using the token from cookies) and client-side rendering (using the token from localStorage)? 2. Are there any other better solutions? Thanks a lot
11 replies
SSolidJS
Created by hannus on 1/26/2024 in #support
renderToString not work
I have two questions about SSR: 1. It cannot work according to document about renderToString. The browser always plain when the response is a string by renderToString. However, If the response is string that I need not to use renderToString, it works well. The code is following: import { renderToString } from "solid-js/web"; function Test() { return <div>Hello World</div>; } const server = Bun.serve({ port: 3999, fetch(request) { const html = renderToString(() => <Test />); return new Response(html, { }); // return new Response("Welcome to Bun!"); }, }); console.log(Listening on localhost:${server.port}); 2. Is solidStart too complicated to the only purpose for SSR? I just want to change my tiny project from CSR to SSR. thanks a lot.
6 replies
SSolidJS
Created by hannus on 12/17/2023 in #support
does Effect have a number limit?
I mean whether the numbers of createEffect have a limit or official advice? For instance, In the user authenticating scenario , I have created an effect to set the state as user logged in successful and then set the access token signal, so that resource could be created by the token as the source signal . What's more, there is another effect I have created to refresh the token signal when access token has expired . In this effect, a function will be called to refresh access token and return a valid one when the response of resource implied token expired information. Is two effects or even more in an APP proper? By the way, which is the better choice between function and async function the second effect? I think normal function is better, because that the token should be refreshed firstly. Or any other advices? thanks a lot
2 replies
SSolidJS
Created by hannus on 12/15/2023 in #support
does createResource with multiple signals trigger when onMount
if createResource has one signal which is false as dependency, the resource will be trigger as the signal changing. However, if I set two signals as dependency, the resource triggers in every mount alougth the signals are false . Is there any methods to avoid trigger fetcher when the group signals are false? thanks a lot
6 replies
SSolidJS
Created by hannus on 11/19/2023 in #support
how to trigger the fetcher in createResource if there are multiple signal values?
hello, newbie here. In the document, it could be create a Memo as a group of signals as following. What's changed could be trigger the fetcher? id() or name()? or both? thanks a lot import { createResource, createMemo } from "solid-js"; // the fetcher function changed to accept an object async function fetcherFunc(info: { id: number; name: string }) { const response = await fetch( https://jsonplaceholder.typicode.com/users/${info.id}/posts?name=${info.name} ); return await response.json(); } const [id, setId] = createSignal<number>(1); const [name, setName] = createSignal<string>(""); // the derived state made using createMemo const derivedState = createMemo(() => ({ id: id(), name: name() })); const [posts] = createResource(derivedState, fetcherFunc);
3 replies