I have a SvelteKit route with a +page.server.ts file which has a load function that retrieves a user record from a database. The user has a string property containing a comma delimited list of "collection" ids that user has access to. In the +page.svelte page, I display a form with checkboxes for each collection to allow an admin user to grant or revoke permissions to collections. Here is my code for displaying the checkboxes
<form method="post" action="?/setCollections" use:enhance>
<input type="hidden" name="email" value={data.user.email} />
<fieldset style:padding-left="1rem">
{#each data.collections as collection (collection.id)}
<div style:margin-bottom=".5rem">
<input
id={collection.name}
name={collection.name}
type="checkbox"
value={collection.id}
checked={data.user.collections?.includes(collection.id)}
/>
<label for={collection.name}>
<small>{collection.name} ({data.user.collections?.includes(collection.id)})</small>
</label>
</div>
{/each}
</fieldset>
<button style:margin-top="1rem" type="submit">Save</button>
</form>
On page load, it is displaying the checkboxes correctly. However, in the scenario where checkboxes B and C are checked, and the admin user checks checkbox A with the intention of giving the user access to A, B and C and submits the form, the page rerenders and only checkbox A is left in the checked state. I can't figure out why this is happening, because the value passed to the checked property for checkboxes B and C is still true, as can be seen by the debug text in the label
The form action is defined in the +page.server.ts actions object, and is here. My method for iterating the checkbox values is probably not ideal but I do not think this is the issue, as the value in the database is being updated correctly.
setCollections: async ({ request }) => {
const data = await request.formData();
const email = data.get('email')?.toString();
// Pop email from values so we can iterate only the checkboxes
data.delete('email');
let collections = '';
// Iterate collections and add to the string
for (const [key, value] of data.entries()) {
collections += value;
const nextVal = [...data.keys()].pop();
// Delimit with a comma if not the last item
if (nextVal && data.get(nextVal) !== data.get(key)) collections += ',';
}
const client = new DynamoDBClient();
const docClient = DynamoDBDocumentClient.from(client);
const updateCommand: UpdateCommandInput = {
TableName: 'users',
Key: {
email
},
UpdateExpression: 'set collections = :collections',
ExpressionAttributeValues: {
':collections': collections
}
};
const command = new UpdateCommand(updateCommand);
const response = await docClient.send(command);
return { message: 'User collection permissions were updated.' };
}
This is probably due to my lack of knowledge in something related to SvelteKit. I have tried assigning the collections to a variable on page load instead like $: collections = data.user?.collections.split(",") ?? []
and using bind:group on this variable, but still does not work and I can't seem to find my mistake.
Comments
Post a Comment