Habits from a File
A new tracker should start with a few suggestions, and yours will load them from a file, as the café loaded its menu in the lesson Lifecycle and Data. They're in habits.json, in the last tab: the three habits from App.vue and two more, so that you can see when the list comes from the file.
The app loads the file in onMounted, once the component is on the page. Until the file arrives, habits is an empty array, and two more refs say what's happening: loading is true until the answer comes, and error gets a message when the file can't be loaded:
const habits = ref([]);
const loading = ref(true);
const error = ref("");
onMounted(async () => {
const response = await fetch("habits.json");
if (!response.ok) {
error.value = "The habits couldn't be loaded.";
} else {
habits.value = await response.json();
}
loading.value = false;
});
Why not just await fetch() at the top of <script setup>? As you saw in the lesson Lifecycle and Data, the component then shows nothing at all. With onMounted, the page is there right away, and the habits come a moment later.
The template shows one of three things: while the file is loading, a message that says so; when there's an error, the error; and otherwise the list. The elements with v-if, v-else-if and v-else have to come right after each other:
<p v-if="loading">Loading…</p>
<p v-else-if="error" class="error">{{ error }}</p>
<ul v-else class="habits">
The class error makes the message red; you'll find it in style.css.
Typical mistakes:
- Forgetting
.value:habits = await response.json();tries to put the array into the constant itself, and the console showsTypeError: Assignment to constant variable. - Forgetting
awaitbeforeresponse.json().habitsthen holds a Promise instead of the array, and the list stays empty.
Instructions
- 1
In the script, replace the array of habits with the code from above, all of it, and add
onMountedto the import from"vue"(the names in alphabetical order:import { onMounted, ref } from "vue";). After a moment, the page shows five habits. - 2
In the template, show
Loading…or the error in front of the list, with the elements from above (theulgetsv-else, and its content stays as it is). To see the error, change the file's name infetch()tohabitz.json, a file that doesn't exist, and run the code. Then change it back.