'Svelte derived store returns incorrect value
I have a problem with derived store, which somehow returns an empty result even tho in the store is 1 record. The derived store depends on 2 writable stores: assignedAgentsIds (array of agent ids) and agents (map of agent entity). If I use both stores directly in a component, it works just fine, but when I use them in a derived store and try to combine them, I'm always getting empty array.
Here is my store code:
const createAssignedAgentsStore = () => {
const assignedAgentIds = writable<string[]>([])
const { subscribe, set, update } = assignedAgentIds
const setAssignedAgentIds = (agentIds: string[]) => {
set(agentIds)
}
const addAssignedAgentId = (agentId: string) => {
update((agentIds) => [...agentIds, agentId])
}
return {
subscribe,
setAssignedAgentIds,
addAssignedAgentId,
}
}
export const assignedAgentIds = createAssignedAgentsStore()
export const assignedAgents = derived([assignedAgentIds, agents], ([$assignedAgentIds, $agents]): Agent[] => {
const assignedAgentsArr: Agent[] = []
for (const agentId of $assignedAgentIds) {
const agent = $agents[agentId]
if (agent) assignedAgentsArr.push(agent)
}
return assignedAgentsArr
})
I tried to debug both $assignedAgentIds and $agents inside derived store, it has correct values and if there is 1 id in assignedAgentsIds and 1 record with the same id in agents map, still when I use $assignedAgents store in component, I get empty array instead of an array with 1 entity.
Edit
In Svelte component, I had this code to show correct type of agents which was also using assignedAgents store:
let headerAgents: Agent[] = []
$: {
let agentsArray = Object.values($agents)
if ($assignedAgents.length > 0) {
agentsArray = $assignedAgents
}
headerAgents = agentsArray.splice(0, 3)
}
Solution 1:[1]
I was passing reference to the assignedAgents store in component and mutating the store with splice function. Solution is to not mutate store by using slice function.
This is code that works:
let headerAgents: Agent[] = []
$: {
let agentsArray = Object.values($agents)
if ($assignedAgents.length > 0) {
agentsArray = $assignedAgents
}
headerAgents = agentsArray.slice(0, 3)
}
Solution 2:[2]
The code looked fine to me, so I just tried to run it and it worked. At least when the agents store is correctly in scope. Though it will throw if it isn't.
Full example:
<script>
import { writable, derived } from 'svelte/store';
const createAssignedAgentsStore = () => {
const assignedAgentIds = writable([])
const { subscribe, set, update } = assignedAgentIds
const setAssignedAgentIds = (agentIds) => {
set(agentIds)
}
const addAssignedAgentId = (agentId) => {
update((agentIds) => [...agentIds, agentId])
}
return {
subscribe,
setAssignedAgentIds,
addAssignedAgentId,
}
}
const assignedAgentIds = createAssignedAgentsStore()
const agents = writable({
0: 'Joe',
1: 'Jane',
2: 'Steve',
});
const assignedAgents = derived(
[assignedAgentIds, agents],
([$assignedAgentIds, $agents]) => {
const assignedAgentsArr = []
for (const agentId of $assignedAgentIds)
{
const agent = $agents[agentId]
if (agent) assignedAgentsArr.push(agent)
}
return assignedAgentsArr
}
)
assignedAgentIds.setAssignedAgentIds([1, 2]);
</script>
{#each $assignedAgents as agent}
<p>{agent}</p>
{/each}
I suspect the issue is elsewhere.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | H.B. |
