createSignal equals: false on mutable object value

Hi guys, I have a resource source signal with { equals: false } that does not trigger fetching unless I wrap and deep copy the object literal value in the source param. The value itself is a propety of an instance wrapped with createMutable, which I suspect is at the crux of this. But why? I though equals: true would guarantee a truthy source signal on setting?
const muatable = createMutable(myClassInstance)
[...]
const [onSaveSignal, setSaveSignal] = createSignal(mutable.data, { equals: false })
[...]
createResource(
onSaveSignal,
(sigObjValue) => {
fetch...
}
);
const muatable = createMutable(myClassInstance)
[...]
const [onSaveSignal, setSaveSignal] = createSignal(mutable.data, { equals: false })
[...]
createResource(
onSaveSignal,
(sigObjValue) => {
fetch...
}
);
Above not working, below working.
createResource(
() => deepCopy(onSaveSignal()),
(sigObjValue) => {
fetch...
}
);
createResource(
() => deepCopy(onSaveSignal()),
(sigObjValue) => {
fetch...
}
);
shallow structuredClone also fails.
17 Replies
REEEEE
REEEEE4w ago
Signals definitions aren't reactive meaning that createSignal(mutable.data) won't be updated with the latest mutable.data when it changes
Flemming
FlemmingOP4w ago
Hmm, still the isgnal triggers as I can debug from within { equals: () => { ... })
REEEEE
REEEEE4w ago
If you're writing to the signal somewhere, it will still fire the equals check
Flemming
FlemmingOP4w ago
Yes, that is the case. Therefore I assumed { equals: false } would work.
REEEEE
REEEEE4w ago
How are you writing to the signal?
Flemming
FlemmingOP4w ago
setSaveSignal(mutable.data)
REEEEE
REEEEE4w ago
Hmm Looks like createResource will memo the source signals
Flemming
FlemmingOP4w ago
Sth along those lines would explain it, but reading the documentation, that is excatly what { equals: false } should circumvent?
REEEEE
REEEEE4w ago
maybe a small change that could work is to do () => ({data: onSaveSignal()}) The memo has it's own equals handling By default it checks via ===
Flemming
FlemmingOP4w ago
I tested now, just give me a few sec to double check that I have doen it right... Yes that works with { equals: false }
const [onFilterListings, setFilterListings] =
createSignal<FilterSchemaType | null>(null, {
equals: false
});

const [filteredListings, { mutate: mutateFilteredListings }] = createResource(
// Need a deep-copy for sourcesignal to diff on data-content
() => ({ filters: onFilterListings() }),
async ({ filters }) => {
console.log('onFilterListings', { filters });
const listings = await listingService.loadListingsByFilters(filters!);
return listings;
},
);
const [onFilterListings, setFilterListings] =
createSignal<FilterSchemaType | null>(null, {
equals: false
});

const [filteredListings, { mutate: mutateFilteredListings }] = createResource(
// Need a deep-copy for sourcesignal to diff on data-content
() => ({ filters: onFilterListings() }),
async ({ filters }) => {
console.log('onFilterListings', { filters });
const listings = await listingService.loadListingsByFilters(filters!);
return listings;
},
);
But, this should also work without { equals: false } ? Due to shallow comparison?
REEEEE
REEEEE4w ago
yeah it should but you have to make sure when you set setFilterListings it's a new obj otherwise the signals default equality === will pass
Flemming
FlemmingOP4w ago
Hmm, I see what you mean, but then the case is that { equals: false } is a bit misleading? It swithches from deep (?) to shallow checking, or s.th? Nah, the docs explicitly says that it will overrride whatever.
REEEEE
REEEEE4w ago
{equals: false} is to explicitly make it so no matter what you set the value to (it could literally be the same value again), it will trigger anything that's listening to the signal
Flemming
FlemmingOP4w ago
Okay, see your point There is another memo in the resource source *on
REEEEE
REEEEE4w ago
Memos have the same equals handling but you have to also set that yourself but createResource doesn't expose a way to set that right now In the eyes of the memo for resource, your previous object and your next object are equal so it doesn't rerun Because they're the same obj
Flemming
FlemmingOP4w ago
Yup, I understand! Thank you very much for taking the time!
REEEEE
REEEEE4w ago
No problem!

Did you find this page helpful?