DEV Community

Shivam Sahu
Shivam Sahu

Posted on • Edited on

Async/Await : Zero to Hero πŸš€

Why async/await in Angular ? πŸ€”

In Angular, many tasks, like fetching data from a server, can take time.
Normally, we use .subscribe() for handling these tasks, but it can get messy when we have to chain many steps or make the code look messy.

this.apiService.getData().subscribe(response => {
  console.log('First API Response:', response);

  this.apiService.getMoreData(response.id).subscribe(moreResponse => {
    console.log('Second API Response:', moreResponse);

    this.apiService.getDetails(moreResponse.detailId).subscribe(detailResponse => {
      console.log('Third API Response:', detailResponse);
    });
  });
});

Enter fullscreen mode Exit fullscreen mode

That's where async and await come in! They help us handle these tasks in a much cleaner, easier-to-read way.

import { firstValueFrom } from 'rxjs';

async fetchData() {
  try {
    const response = await firstValueFrom(this.apiService.getData());
    console.log('First API Response:', response);

    const moreResponse = await firstValueFrom(this.apiService.getMoreData(response.id));
    console.log('Second API Response:', moreResponse);

    const detailResponse = await firstValueFrom(this.apiService.getDetails(moreResponse.detailId));
    console.log('Third API Response:', detailResponse);
  } catch (error) {
    console.error('Error occurred:', error);
  }
}

Enter fullscreen mode Exit fullscreen mode

With async/await, the code runs one step at a time without getting messy. It’s easy to read, easy to fix if something goes wrong, and you can catch all errors in one place. Even though it works in the background, the code looks simple and clean.

What is async/await in Angular ? πŸ“š

async is a keyword that we put in front of a function to tell it,

'Hey, this function is going to handle something that takes time.'

And await is used inside that function to wait for something to finish before moving to the next line of code.

async getData() {
  const result = await this.http.get('https://api.example.com/users').toPromise();
  console.log(result);
}
Enter fullscreen mode Exit fullscreen mode

Here, await tells Angular to wait for the data before moving forward.

Without await, the code would keep running without waiting for the response, which might cause issues.

How to use async/await in Angular ? πŸ”§

Step 1: Add async to your function.

async ngOnInit() {
  // your code here
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Use await inside the function to wait for something.

async ngOnInit() {
  const data = await this.http.get('/api/data').toPromise();
  console.log(data);
}
Enter fullscreen mode Exit fullscreen mode

Step 3: If you’re using HttpClient, make sure to convert the Observable to a Promise (use .toPromise() or firstValueFrom()).

import { firstValueFrom } from 'rxjs';

async getData() {
  const data = await firstValueFrom(this.http.get('/api/data'));
  console.log(data);
}
Enter fullscreen mode Exit fullscreen mode

Real-world example ? 🌍

A practical use of async/await is in dependent dropdowns. For example, when a user selects a country, we need to fetch the states related to that country from the server.

Using async/await, we can wait for the states to load first, and only then populate the next dropdown, ensuring a smooth user experience without race conditions.

async onCountryChange(countryId: number) {
  this.states = await this.locationService.getStatesByCountry(countryId);
}
Enter fullscreen mode Exit fullscreen mode

Avoid mistakes when using async/await ? ⚠️

❌ Don't use await outside an async function.

ngOnInit() {
  const user = await this.userService.getUser(); // ❌ Error: 'await' is only valid in async functions
  console.log(user);
}
Enter fullscreen mode Exit fullscreen mode

βœ… Correct: Mark the function async

async ngOnInit() {
  const user = await this.userService.getUser(); 
  console.log(user);
}
Enter fullscreen mode Exit fullscreen mode

❌ Don't mix await with subscribe() from RxJS. Use firstValueFrom() to convert Observables.

async fetchData() {
  const data = await this.apiService.getData().subscribe(response => {
    console.log(response);
  });
}
Enter fullscreen mode Exit fullscreen mode

βœ… Correct: Use firstValueFrom()

import { firstValueFrom } from 'rxjs';

async getData() {
  const data = await firstValueFrom(this.apiService.getData());
  console.log(data);
}
Enter fullscreen mode Exit fullscreen mode

❌ Avoid unhandled try/catch. Always catch errors.

async fetchData() {
  const data = await firstValueFrom(this.apiService.getData());
  console.log(data); // ❌ If API fails, app crashes without handling error
}
Enter fullscreen mode Exit fullscreen mode

βœ… Correct: With try/catch (proper error handling)

async fetchData() {
  try {
    const data = await firstValueFrom(this.apiService.getData());
    console.log(data);
  } catch (error) {
    console.error('Failed to fetch data:', error); // βœ… Graceful error handling
  }
}
Enter fullscreen mode Exit fullscreen mode

❌ Avoid using too many sequential await calls if they can be parallelized (performance hit).

async loadDashboard() {
  const profile = await firstValueFrom(this.apiService.getProfile());
  const notifications = await firstValueFrom(this.apiService.getNotifications());
  const messages = await firstValueFrom(this.apiService.getMessages());

  console.log(profile, notifications, messages);
}
Enter fullscreen mode Exit fullscreen mode

βœ… Correct: Parallel await calls using Promise.all() (better performance)

async loadDashboard() {
  const [profile, notifications, messages] = await Promise.all([
    firstValueFrom(this.apiService.getProfile()),
    firstValueFrom(this.apiService.getNotifications()),
    firstValueFrom(this.apiService.getMessages())
  ]);

  console.log(profile, notifications, messages);
}
Enter fullscreen mode Exit fullscreen mode

Most asked interview question on async/await ? 🎯

πŸ”Ή Basic Questions
1️⃣ What is async/await in JavaScript/TypeScript?
πŸ‘‰ Async/await is syntax to handle promises in a cleaner and more readable way, making asynchronous code behave like synchronous code.

2️⃣ Why do we use async/await instead of .then()?
πŸ‘‰ Async/await avoids nested .then() chains and makes error handling with try-catch much simpler.

3️⃣ What does the async keyword do?
πŸ‘‰ It marks a function to always return a promise, even if it returns a simple value.

4️⃣ What does the await keyword do?
πŸ‘‰ It pauses the function execution until the awaited promise is resolved or rejected.

πŸ”Ή Angular-Specific Questions
5️⃣ Where would you typically use async/await inside an Angular application?
πŸ‘‰ In services while calling APIs, in component lifecycle methods (like ngOnInit), and during sequential operations like login ➑️ fetch profile ➑️ load dashboard.

6️⃣ Can we use async/await with HttpClient in Angular?
πŸ‘‰ Yes, but since HttpClient returns Observables, we often convert them to promises using .toPromise() (deprecated) or firstValueFrom() before using await.

7️⃣ Can we use async/await inside Angular services?
πŸ‘‰ Absolutely, services are a common place to write reusable async functions.

πŸ”Ή Practical Scenario-Based Questions
8️⃣ How would you handle multiple API calls using async/await?
πŸ‘‰ Either:

Wait one after another (sequentially)

Or use Promise.all() if APIs are independent and can run in parallel.

9️⃣ What happens if a promise fails inside an async function?
πŸ‘‰ It throws an exception, which we should catch using a try-catch block.

πŸ”Ÿ Can we use async/await inside Angular interceptors?
πŸ‘‰ Yes, interceptors can be async if you return a promise that eventually resolves to an HTTP response.

πŸ”Ή Slightly Advanced Questions
1️⃣1️⃣ What are the drawbacks of async/await?
πŸ‘‰

You cannot run operations in parallel easily without Promise.all().

If many awaits happen sequentially, it can slow down performance.

Error handling can become tricky if you await multiple things without a proper structure.

1️⃣2️⃣ Can you combine async/await and Observables?
πŸ‘‰ Yes!
We usually convert Observables to Promises if we want to use async/await.
Example:

typescript
Copy
Edit
await firstValueFrom(this.api.getData());
πŸ”Ή Bonus: Real-Life Use Case Questions
1️⃣3️⃣ Give one real-world example where async/await helped improve user experience in your project.
πŸ‘‰ Example:

Dependent dropdowns (country β†’ states)

File upload before navigation

Token refresh before API calls

1️⃣4️⃣ How would you handle an API retry if the awaited call fails?
πŸ‘‰ Inside catch block, you can retry the call manually, or use retry strategies with services.

Top comments (0)