Bird
Raised Fist0
Angularframework~20 mins

Facade service pattern in Angular - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Facade Service Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What does this Angular facade service component output?

Consider this Angular component using a facade service to get user data.

import { Component } from '@angular/core';
import { UserFacade } from './user.facade';

@Component({
  selector: 'app-user',
  template: `User: {{ userName }}`
})
export class UserComponent {
  userName = '';
  constructor(private userFacade: UserFacade) {
    this.userFacade.getUserName().subscribe(name => this.userName = name);
  }
}

The UserFacade returns an observable emitting 'Alice'.

What will the component display?

Angular
import { Injectable } from '@angular/core';
import { of } from 'rxjs';

@Injectable({ providedIn: 'root' })
export class UserFacade {
  getUserName() {
    return of('Alice');
  }
}
AUser: undefined
BUser: Alice
CUser: null
DUser: '' (empty string)
Attempts:
2 left
💡 Hint

Think about what the observable emits and how the subscription updates userName.

state_output
intermediate
1:30remaining
What is the value of isLoading after facade call?

Given this Angular facade service and component snippet:

export class DataFacade {
  isLoading = false;
  fetchData() {
    this.isLoading = true;
    setTimeout(() => this.isLoading = false, 1000);
  }
}

@Component({ selector: 'app-data', template: `Loading: {{ facade.isLoading }}` })
export class DataComponent {
  constructor(public facade: DataFacade) {
    this.facade.fetchData();
  }
}

Immediately after fetchData() is called, what is the value of facade.isLoading?

Atrue
Bfalse
Cundefined
Dnull
Attempts:
2 left
💡 Hint

Consider the synchronous and asynchronous parts of fetchData().

📝 Syntax
advanced
2:30remaining
Which option correctly injects a facade service in Angular 17 standalone component?

Angular 17 supports standalone components and the new inject() function.

Which code snippet correctly injects UserFacade in a standalone component?

A
@Component({ standalone: true, selector: 'app-user', template: '' })
export class UserComponent {
  userFacade = inject(UserFacade);
}
B
const userFacade = inject(UserFacade);

@Component({ standalone: true, selector: 'app-user', template: '' })
export class UserComponent {
  constructor() {
    console.log(userFacade);
  }
}
C
@Component({ standalone: true, selector: 'app-user', template: '' })
export class UserComponent {
  constructor(private userFacade: UserFacade) {}
}
D
@Component({ standalone: true, selector: 'app-user', template: '' })
export class UserComponent {
  userFacade = new UserFacade();
}
Attempts:
2 left
💡 Hint

Remember that inject() is used inside class bodies, not outside.

🔧 Debug
advanced
2:30remaining
Why does this facade service cause a memory leak?

Look at this Angular facade service:

@Injectable({ providedIn: 'root' })
export class ProductFacade {
  products$;
  constructor(private api: ApiService) {
    this.products$ = this.api.getProducts();
  }
}

The component subscribes to products$ but never unsubscribes. Why is this a problem?

ABecause <code>products$</code> is a cold observable and never completes, causing subscriptions to stay active.
BBecause the facade service is not provided in the component, so Angular creates multiple instances.
CBecause the component should unsubscribe manually to avoid memory leaks from long-lived subscriptions.
DBecause the facade does not use <code>shareReplay</code> or caching, causing multiple API calls.
Attempts:
2 left
💡 Hint

Think about Angular subscriptions and component lifecycle.

🧠 Conceptual
expert
2:00remaining
Which statement best describes the main benefit of the facade service pattern in Angular?

Choose the best explanation of why using a facade service is helpful in Angular applications.

AIt forces all components to share the same service instance, preventing any state duplication.
BIt replaces Angular's dependency injection system with a manual service locator pattern.
CIt automatically caches all API responses to improve performance without extra code.
DIt hides complex state management and API calls behind a simple interface, reducing component complexity and improving maintainability.
Attempts:
2 left
💡 Hint

Think about how facades simplify component code and separate concerns.

Practice

(1/5)
1.

What is the main purpose of using a Facade Service in Angular?

easy
A. To directly manipulate the DOM from services
B. To replace Angular modules with a single service
C. To simplify component code by hiding complex service logic behind simple methods
D. To create multiple instances of services for each component

Solution

  1. Step 1: Understand the role of Facade Service

    A Facade Service acts as a simple interface hiding complex logic from components.
  2. Step 2: Identify the benefit in Angular components

    This pattern keeps components clean and easier to maintain by centralizing service calls.
  3. Final Answer:

    To simplify component code by hiding complex service logic behind simple methods -> Option C
  4. Quick Check:

    Facade Service purpose = Simplify logic [OK]
Hint: Facade hides complexity behind simple methods [OK]
Common Mistakes:
  • Thinking Facade replaces Angular modules
  • Believing Facade manipulates DOM directly
  • Assuming Facade creates multiple service instances
2.

Which of the following is the correct way to inject a facade service MyFacadeService into an Angular component constructor?

easy
A. constructor(private myFacadeService: MyFacadeService) {}
B. constructor(public MyFacadeService) {}
C. constructor(myFacadeService: new MyFacadeService()) {}
D. constructor(private myFacadeService = MyFacadeService) {}

Solution

  1. Step 1: Recall Angular dependency injection syntax

    Angular injects services via constructor parameters with access modifiers and type annotations.
  2. Step 2: Match correct syntax

    constructor(private myFacadeService: MyFacadeService) {} uses private and type MyFacadeService, which is correct.
  3. Final Answer:

    constructor(private myFacadeService: MyFacadeService) {} -> Option A
  4. Quick Check:

    Inject service with private + type [OK]
Hint: Use private and type in constructor for injection [OK]
Common Mistakes:
  • Omitting access modifier (private/public)
  • Using new keyword inside constructor parameters
  • Assigning service without type annotation
3.

Given this facade service method:

getUserName(): Observable<string> {
  return this.userService.getUser().pipe(
    map(user => user.name)
  );
}

What will the component receive when subscribing to getUserName()?

medium
A. A synchronous string value of the user's name
B. An observable emitting the entire user object
C. A promise resolving to the user's name
D. An observable emitting the user's name as a string

Solution

  1. Step 1: Analyze the facade method return type

    The method returns an Observable<string> by mapping the user object to user.name.
  2. Step 2: Understand what subscribing receives

    Subscribing to this Observable emits the user's name string asynchronously.
  3. Final Answer:

    An observable emitting the user's name as a string -> Option D
  4. Quick Check:

    Facade returns Observable of user name [OK]
Hint: Facade returns Observable mapped to user name [OK]
Common Mistakes:
  • Confusing Observable with Promise
  • Expecting synchronous value instead of Observable
  • Assuming entire user object is emitted
4.

Identify the error in this facade service method:

fetchData() {
  this.apiService.getData().subscribe(data => {
    this.data = data;
  });
  return this.data;
}
medium
A. Using arrow function inside subscribe is invalid syntax
B. Returns data before subscription completes, causing undefined result
C. Subscription should be inside component, not service
D. Missing return type annotation causes compile error

Solution

  1. Step 1: Understand asynchronous subscription

    The subscribe callback runs later, so this.data is not set immediately.
  2. Step 2: Identify return timing issue

    The method returns this.data immediately, likely undefined before data arrives.
  3. Final Answer:

    Returns data before subscription completes, causing undefined result -> Option B
  4. Quick Check:

    Async subscribe returns undefined early [OK]
Hint: Return inside subscribe or use Observable return [OK]
Common Mistakes:
  • Returning data before async call finishes
  • Thinking arrow functions are invalid in subscribe
  • Believing subscription must be in component only
5.

You want to create a facade service that combines data from UserService and SettingsService and exposes a single observable userSettings$. Which approach correctly implements this?

class UserSettingsFacade {
  userSettings$: Observable<UserSettings>;

  constructor(private userService: UserService, private settingsService: SettingsService) {
    // Fill in here
  }
}
hard
A. this.userSettings$ = combineLatest([this.userService.getUser(), this.settingsService.getSettings()]).pipe(map(([user, settings]) => ({ user, settings })));
B. this.userSettings$ = this.userService.getUser().pipe(map(user => this.settingsService.getSettings()));
C. this.userSettings$ = this.userService.getUser() + this.settingsService.getSettings();
D. this.userSettings$ = forkJoin(this.userService.getUser(), this.settingsService.getSettings());

Solution

  1. Step 1: Combine multiple observables correctly

    Use combineLatest to emit latest values from both observables together.
  2. Step 2: Map combined values into single object

    Use map operator to create an object with user and settings properties.
  3. Final Answer:

    this.userSettings$ = combineLatest([this.userService.getUser(), this.settingsService.getSettings()]).pipe(map(([user, settings]) => ({ user, settings }))); -> Option A
  4. Quick Check:

    Use combineLatest + map to merge observables [OK]
Hint: Use combineLatest and map to merge observables [OK]
Common Mistakes:
  • Using + operator to add observables
  • Mapping one observable to another observable instead of values
  • Using forkJoin which waits for all to complete once