Derrived Signal With A Ressource

Hi! That might be an easy one. I get a resource from a Context called userData. What is the proper way to derrive further signals or just values from it? The following example doesn´t seem correct and I think it smells. const {userData: [user]} = useAuth(""); // When the component renders, user is not defined yet. const [userInitials, setUserInitials] = createSignal<string>(""); createEffect(() => { if(user.state === "ready") { // as soon user is there, I set the initials-signal. setUserInitials(user().firstName.slice(0, 1) + user().lastName.slice(0, 1)); } })
5 Replies
bigmistqke
bigmistqke3mo ago
Something like
const userInitials = () => user() ? `${user()!.firstName.slice(0,1)} ${user()!.lastName.slice(0,1}` : undefined
const userInitials = () => user() ? `${user()!.firstName.slice(0,1)} ${user()!.lastName.slice(0,1}` : undefined
peerreynders
peerreynders3mo ago
See also derived signals and createMemo. The important thing to remember is that the JSX returned by a component exists within an implicit reactive scope which is sufficient for a derived signal to subscribe to its dependencies. So if userInitials is just used once in the returned JSX then a derived signal is more than enough. However each access will re-run the entire derived signal. Again, not a big deal if the derived signal isn't doing anything complicated. However once you pass it as a prop where it may be accessed who-knows-how-many-times, wrapping it in a createMemo is probably a good idea. The memo will then only rerun the function whenever one of the dependencies change, itself always returning the value of the latest run. If you want to stay away from non-null assertion operators then just write it like this:
const userInitials = () => {
const record = user();
return record
? `${record.firstName.slice(0, 1)} ${record.lastName.slice(0, 1)}`
: '';
};
const userInitials = () => {
const record = user();
return record
? `${record.firstName.slice(0, 1)} ${record.lastName.slice(0, 1)}`
: '';
};
The verbosity is a concession to the fact that TypeScript treats Accessors as functions rather than getters which don't tend to change value during synchronous execution of a script.
MDN Web Docs
get - JavaScript | MDN
The get syntax binds an object property to a function that will be called when that property is looked up. It can also be used in classes.
Paradinio
ParadinioOP3mo ago
Thanks a lot for your great responses! That´s definitly what I was searching for. 🙂 Okey, but to take it further: In this case, I´m loosing my Setter-Function for the userInitials (Just as an example, I know, I don´t really need a stter for user-initials). What, if I want to initialize a Signal with the user() as soon it is not null anymore, but then set the new Signal independently again? Let´s say f.e. for a controlled inputField?
peerreynders
peerreynders3mo ago
See: https://discord.com/channels/722131463138705510/722131463889223772/1335413663368220712 With createWritableMemo you can specify an initial value. Then in the effect function you just keep the previous value if user() is undefined. In general: - you only use the setter when you temporarily "know better" but - you still want to update based on the primary dependency but only if it updates after you set it. afaik: Solid 2.x signals will simply work that way; follow the dependencies, over-rideable via setter.
Paradinio
ParadinioOP3mo ago
Very interesting!, what Ryan writes in his blog post! That createWritableMemo will save me a lot of uneccessary unpredicatable code i think. Thank you sir!

Did you find this page helpful?