I'm struggling with a timing issue in which I'm getting an error because the data response from the API I'm fetching is not done before trying to process the data.
Here is my example:
### Template
<div class="container mx-auto" x-data="loadIdentities()">
<template x-for="item in filteredIdentities" :key="item">
<h6 x-text="item.name"></h6>
<em x-text="item.role"></em>
</template>
</div>
### SCRIPT
<script>
function loadIdentities() {
return {
search: "",
myData: "",
get filteredIdentities() {
fetch(`/api_endpoint`)
.then(res => res.json())
.then(data => {
this.myData = data
}
)
var foundIdentities = this.myData.filter((item) => {
return item.name
.toLowerCase()
.includes(this.search.toLowerCase());
});
return foundIdentities
},
};
}
</script>
Uncaught TypeError: this.myForData.filter is not a function
Is there a nice way that I can have the processing of the javascript wait for the API request to complete and the data to populate from the API?
You can also return an empty array as long as there is no data to display.
Example:
(here I load the Identities once using the init() method and then filter using the getFilteredIdentities method)
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<script src="//unpkg.com/alpinejs" defer></script>
<div class="p-5 mx-auto" x-data="loadIdentities()">
<input class="border px-2" placeholder="Filter Identities..." x-model="search"
x-on:change="setFilteredItentities()" />
<p class="text-gray-400" x-show="isLoading">Loading Identities...</p>
<template x-for="item in getFilteredIdentities" :key="item.id">
<div class="mt-2 flex items-center">
<h6 x-text="item.first_name"></h6>
<p class="text-xs text-gray-500 ml-2" x-text="item.email"></p>
</div>
</template>
</div>
<script>
function loadIdentities() {
return {
search: "",
isLoading: false,
allIdentities: [],
init() {
this.isLoading = true
fetch(`https://reqres.in/api/users`)
.then(res => res.json())
.then(data => {
this.allIdentities = data.data
})
this.isLoading = false;
},
getFilteredIdentities() {
if (!this.allIdentities || !this.search) {
return this.allIdentities
}
var result = this.allIdentities.filter((item) => {
return item.first_name
.toLowerCase()
.includes(this.search.toLowerCase());
})
return result
}
}
}
</script>
You can use await. Declare the function as async like: async function filteredIdentities (){
const response = await fetch('stuff')
const data = await response.json()
return data.filter((item) =>
return item.name
.toLowerCase()
.includes(this.search.toLowerCase());
});
}
The function return a promise and when It Will resolved you have an array