Bird
Raised Fist0
Vueframework~10 mins

Composable for API calls (useFetch pattern) in Vue - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Composable for API calls (useFetch pattern)
Component calls useFetch
↓
useFetch starts: set loading=true
↓
Send fetch request
↓
Wait for response
↓
If success: set data, loading=false
↓
If error: set error, loading=false
↓
Component reacts to data/error changes
The component calls the composable, which starts loading and sends a fetch request. When the response arrives, it updates data or error and stops loading. The component updates accordingly.
Execution Sample
Vue
import { ref } from 'vue';

export function useFetch(url) {
  const data = ref(null);
  const error = ref(null);
  const loading = ref(true);

  fetch(url)
    .then(res => res.json())
    .then(json => { data.value = json; loading.value = false; })
    .catch(err => { error.value = err.message; loading.value = false; });

  return { data, error, loading };
}
This composable fetches data from the given URL and tracks loading, data, and error states.
Execution Table
StepActionState BeforeState AfterNotes
1Call useFetch with URLdata=null, error=null, loading=undefineddata=null, error=null, loading=trueLoading starts
2Send fetch requestloading=trueloading=trueWaiting for response
3Receive response (success)data=null, loading=truedata=JSON data, loading=falseData set, loading ends
4Component reads datadata=JSON datadata=JSON dataComponent updates UI
5If error occurserror=null, loading=trueerror=error message, loading=falseError set, loading ends
6Component reads errorerror=error messageerror=error messageComponent shows error
7Exitloading=falseloading=falseFetch complete, no more changes
💡 Fetch completes either with data or error, loading becomes false, stopping further updates.
Variable Tracker
VariableStartAfter Step 1After Step 3 (success)After Step 5 (error)Final
datanullnullJSON datanullJSON data or null
errornullnullnullerror messagenull or error message
loadingundefinedtruefalsefalsefalse
Key Moments - 3 Insights
Why does loading start as true immediately after calling useFetch?
Loading is set to true right after calling useFetch to show the component that data is being fetched. See execution_table step 1 where loading changes from undefined to true.
What happens if the fetch request fails?
If fetch fails, error is set with the error message and loading becomes false, as shown in execution_table step 5. The component can then show the error.
Why does the component update when data or error changes?
Because data, error, and loading are reactive refs, Vue tracks their changes and updates the component automatically, as seen in steps 4 and 6.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of loading after step 3?
Afalse
Btrue
Cnull
Dundefined
💡 Hint
Check the 'State After' column in step 3 where loading changes after data is set.
At which step does the error variable get a value?
AStep 2
BStep 5
CStep 3
DStep 4
💡 Hint
Look for the step where error changes from null to an error message in the execution_table.
If the fetch request takes longer, which variable stays true longer?
Adata
Berror
Cloading
Durl
💡 Hint
Refer to variable_tracker and execution_table steps showing loading true during fetch.
Concept Snapshot
Composable useFetch pattern:
- Call useFetch(url) in component
- Returns reactive refs: data, error, loading
- loading=true while fetching
- On success: data set, loading=false
- On error: error set, loading=false
- Component auto-updates on ref changes
Full Transcript
This visual execution shows how a Vue composable called useFetch works step-by-step. When a component calls useFetch with a URL, it sets loading to true and sends a fetch request. While waiting, loading stays true. When the response arrives successfully, data is set with the JSON result and loading becomes false. If an error happens, error is set with the message and loading becomes false. The component watches these reactive variables and updates its display automatically. The execution table tracks each step's state changes, and the variable tracker shows how data, error, and loading change over time. Key moments clarify why loading starts true, what happens on error, and how reactivity triggers UI updates. The quiz tests understanding of loading state, error assignment, and fetch timing.

Practice

(1/5)
1. What is the main purpose of a composable like useFetch in Vue?
easy
A. To fetch data from an API and manage loading and error states reactively
B. To style components with CSS variables
C. To create Vue directives for DOM manipulation
D. To define routes in a Vue application

Solution

  1. Step 1: Understand composable role

    A composable in Vue is a reusable function that encapsulates logic, often for state or side effects.
  2. Step 2: Identify useFetch purpose

    The useFetch composable specifically handles API calls and manages reactive states like loading and error.
  3. Final Answer:

    To fetch data from an API and manage loading and error states reactively -> Option A
  4. Quick Check:

    Composable useFetch = fetch + reactive states [OK]
Hint: Composable useFetch manages API data and states reactively [OK]
Common Mistakes:
  • Confusing composables with styling or routing
  • Thinking composables only handle UI rendering
  • Assuming composables are Vue components
2. Which of the following is the correct way to import and use a useFetch composable in a Vue component?
easy
A. const { useFetch } = Vue; const result = useFetch(url);
B. import useFetch from 'vue'; const data = useFetch(url);
C. import { useFetch } from '@/composables/useFetch'; const { data, error } = useFetch(url);
D. import { fetchData } from '@/composables'; fetchData(url);

Solution

  1. Step 1: Check import syntax

    The composable is usually exported from a file and imported with curly braces if it's a named export.
  2. Step 2: Using the composable

    Calling useFetch(url) returns reactive properties like data and error.
  3. Final Answer:

    import { useFetch } from '@/composables/useFetch'; const { data, error } = useFetch(url); -> Option C
  4. Quick Check:

    Correct import + destructure = import { useFetch } from '@/composables/useFetch'; const { data, error } = useFetch(url); [OK]
Hint: Import named composable and destructure returned refs [OK]
Common Mistakes:
  • Importing from wrong path or package
  • Using default import when composable is named export
  • Not destructuring returned reactive properties
3. Given this useFetch composable usage:
const { data, loading, error } = useFetch('https://api.example.com/items');

What will loading.value be immediately after calling useFetch?
medium
A. null
B. true
C. false
D. undefined

Solution

  1. Step 1: Understand loading state in useFetch

    Loading usually starts as true when the fetch begins to indicate data is being fetched.
  2. Step 2: Check initial loading value

    Immediately after calling, loading is true until data or error updates it to false.
  3. Final Answer:

    true -> Option B
  4. Quick Check:

    Loading starts true during fetch [OK]
Hint: Loading is true while fetching data [OK]
Common Mistakes:
  • Assuming loading starts false before fetch
  • Confusing loading with data presence
  • Expecting loading to be null or undefined
4. What is the main issue with this useFetch composable snippet?
export function useFetch(url) {
  const data = ref(null);
  const loading = ref(false);
  const error = ref(null);

  fetch(url)
    .then(res => res.json())
    .then(json => { data.value = json; loading.value = false; })
    .catch(err => { error.value = err; loading.value = false; });

  loading.value = true;
  return { data, loading, error };
}
medium
A. Setting loading.value = true after fetch call starts causes race condition
B. Not using async/await causes syntax error
C. data should be initialized as an empty array, not null
D. Error ref should be initialized as an empty string

Solution

  1. Step 1: Analyze loading state timing

    Loading is set to false inside fetch callbacks but set to true after fetch starts, which can cause timing issues.
  2. Step 2: Identify race condition

    Because loading is set to true after fetch call, it might overwrite loading false set in callbacks if fetch resolves quickly.
  3. Final Answer:

    Setting loading.value = true after fetch call starts causes race condition -> Option A
  4. Quick Check:

    Loading state timing error = Setting loading.value = true after fetch call starts causes race condition [OK]
Hint: Set loading true before fetch call to avoid race [OK]
Common Mistakes:
  • Setting loading true after fetch call instead of before
  • Confusing async/await with promises syntax errors
  • Assuming initial data type must be array
5. You want to create a useFetch composable that automatically retries fetching up to 3 times if the API call fails. Which approach correctly adds this retry logic?
hard
A. Wrap fetch in a try/catch but do not retry on failure
B. Call fetch once and ignore errors, relying on component to retry
C. Use setTimeout outside the composable to call useFetch repeatedly
D. Use a recursive function inside the composable that calls fetch again on error until max retries reached

Solution

  1. Step 1: Understand retry logic needs repeated fetch calls

    Retry means calling fetch again if it fails, up to a limit.
  2. Step 2: Implement retry inside composable

    A recursive or loop function inside composable can retry fetch on error until max retries.
  3. Step 3: Evaluate other options

    Ignoring errors or retrying outside composable breaks encapsulation; try/catch without retry misses requirement.
  4. Final Answer:

    Use a recursive function inside the composable that calls fetch again on error until max retries reached -> Option D
  5. Quick Check:

    Retry logic inside composable = Use a recursive function inside the composable that calls fetch again on error until max retries reached [OK]
Hint: Retry fetch inside composable with recursion or loop [OK]
Common Mistakes:
  • Retrying outside composable losing reactive state control
  • Ignoring errors instead of retrying
  • Not limiting retry attempts causing infinite loops
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard