I am working on a small Users app in Svelte for learning purposes (Im new to Svelte).
In App.Svelte, I loop through a set of users:
<script>
const apiURL = "https://randomuser.me/api/";
import { onMount } from "svelte";
import Search from './Search.svelte';
import User from './User.svelte';
let users = [];
let stringToMatch = "";
$:filteredUsers = users;
onMount(() => {
getUsers();
});
const getUsers = () => {
let getFrom = "&results=20&inc=name,location,email,cell,picture";
fetch(`${apiURL}?${getFrom}`)
.then(res => res.json())
.then((data) => users = data.results);
};
let filterUsers = () => {
if (stringToMatch) {
filteredUsers = users.filter(user => {
return user.name.first.toLowerCase().includes(stringToMatch.toLowerCase()) ||
user.name.last.toLowerCase().includes(stringToMatch.toLowerCase()) ||
user.location.city.toLowerCase().includes(stringToMatch.toLowerCase());
});
} else filteredUsers = users;
};
</script>
<div class="container-fluid">
<div class="card bg-light mb-2 overflow-hidden">
<div class="card-header px-2 py-0 d-flex">
<h6 class="text-dark m-0 align-self-center">Members Area</h6>
</div>
<div class="card-body bg-white p-0">
<Search {filterUsers} bind:stringToMatch={stringToMatch} />
{#if filteredUsers.length > 0}
<table class="table users-table m-0">
<thead>
<tr>
<th class="text-right">#</th>
<th>Name</th>
<th>Lives in</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
{#each filteredUsers as user,index (user)}
<User {user} {index} on:Delete = {deleteUser(user)} />
{/each}
</tbody>
</table>
{:else}
<p class="text-center text-muted my-3">No members found</p>
{/if}
</div>
</div>
</div>
As can be seen in the loop above, I display every user from a User.svelte
component. It seems logical that every user-related action (like deleting a user, for instance) show live in this component. So, it is here that I have:
const dispatch = createEventDispatcher();
const Delete = () => dispatch("deleteUser", user);
const deleteUser = (user) => {
let itemIdx = filteredUsers.findIndex(x => x == user);
filteredUsers.splice(itemIdx, 1);
filteredUsers = filteredUsers;
}
Yet, I get this 'deleteUser' is not defined
error, as can be seen in the REPL.
Question(s)
- What am I doing wrong?
- How can I keep the
deleteUser
method withinUser.svelte
and use it successfully?
You are defining
deleteUser
in theUser
component, but you are trying to use it inApp
were it is indeed not defined. So the error is not that strange imo.One of the problems you have is that your delete function is acting upon an array that is not part of the component (filteredUsers), so even if you would call
deleteUser
directly inside the component you would just get another undefined error.What I see here is that you, logically, want to keep all the logic dealing with an individual user inside
User
, but by doing so you take in logic that deals with the users as whole (the array), which is inconsistent: the users as an array itself is part ofApp
, why would you want to take logic related with the array out of where it belongs ?In my opinion, deleting a user is not a function executed by an item on itself but is a function done by the holder of the array. So in your case you would be better of moving the
deleteUser
up toApp
.If you do it this way, the User component will be responsible for
And the App will be responsible for