Skip to main content
Published / updated

Frontend Choice — Angular or React

Before you start

You need: stage 6. Both frameworks assume HTML, CSS, JavaScript and TypeScript.

Time: 32–40 classes for Angular, 28–36 for React. Choose one.

Learning objective

Choose one framework, learn it properly, and rebuild the stage 6 pages as components calling your API.

Topics

  • What a component framework gives you
  • Choosing between Angular and React
  • Components, state and props
  • Routing
  • Forms and validation
  • Calling the API, with loading and error states
  • Authentication in the browser
  • What both paths share

What this stage covers

Learn one framework well rather than two badly. The concepts transfer — components, state, routing, forms, HTTP — so the second one takes a fraction of the time. Employers hire for one.

AngularReact
TypeFull frameworkA library plus chosen packages
LanguageTypeScript, requiredJavaScript or TypeScript
StructurePrescribedYou decide
Routing, HTTP, formsBuilt inSeparate packages
Learning curveSteeper start, fewer decisionsGentler start, more decisions
Common withEnterprise .NET teamsStartups, product companies
Classes32–4028–36

Choose Angular if you are targeting enterprise Microsoft teams, prefer structure decided for you, or want TypeScript enforced.

Choose React if you want a gentler start, are targeting product companies, or expect to work across smaller codebases.

Neither choice is wrong. Ask what local employers advertise for and pick that. What matters is finishing one.

What both paths share

Whichever you choose, this stage teaches the same eight things:

ConceptAngularReact
Component@Component class with a templateFunction returning JSX
Passing data in@Input()Props
Local stateClass propertyuseState
Side effectsLifecycle hooksuseEffect
RoutingRouterModuleReact Router
FormsReactive formsControlled inputs
HTTPHttpClientfetch or Axios
Auth wiringInterceptor and route guardContext and a wrapper component

Three rules established here recur in every remaining stage:

  • Route guards and hidden buttons are interface, not security. The API from stage 5 enforces permissions; the frontend only avoids showing a user a door they cannot open.
  • Every API call has three states — loading, success, error. Rendering before data arrives is the most common frontend bug in both frameworks.
  • The API base URL is configuration, not a hardcoded string. It differs per environment, and anything prefixed VITE_ is shipped to the browser and therefore not a secret.

Worked flow: the fee receipt

Angular:

@Component({
selector: 'app-fee-receipt',
templateUrl: './fee-receipt.component.html'
})
export class FeeReceiptComponent implements OnInit {
receipt: FeeReceipt | null = null;
isLoading = true;
errorMessage = '';

constructor(
private route: ActivatedRoute,
private feeService: FeeService) { }

ngOnInit(): void {
const paymentId = Number(this.route.snapshot.paramMap.get('paymentId'));

this.feeService.getReceipt(paymentId).subscribe({
next: (receipt) => {
this.receipt = receipt;
this.isLoading = false;
},
error: (error) => {
this.errorMessage = error.status === 404
? 'Receipt not found.'
: 'Could not load the receipt.';
this.isLoading = false;
}
});
}
}

React:

function FeeReceipt() {
const { paymentId } = useParams();
const [receipt, setReceipt] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [errorMessage, setErrorMessage] = useState("");

useEffect(() => {
async function load() {
try {
const data = await getReceipt(paymentId);
setReceipt(data);
} catch (error) {
setErrorMessage(error.status === 404
? "Receipt not found."
: "Could not load the receipt.");
} finally {
setIsLoading(false);
}
}

load();
}, [paymentId]);

if (isLoading) { return <Spinner />; }
if (errorMessage) { return <ErrorMessage text={errorMessage} />; }

return <ReceiptCard receipt={receipt} />;
}

Both render the same receipt for Ravi Kumar (NCA-2024-0012), served by the stage 5 endpoint.

Different syntax, identical shape. Read the route parameter, call the service, track three states, render accordingly.

The [paymentId] dependency array in React and the paramMap snapshot in Angular are both the same trap: navigate from one receipt to another and a missing dependency leaves the old data on screen.

Where to learn it

Angular — Track 11:

TopicRead
Fundamentals and the CLIAngular fundamentals
Templates and bindingTemplates and binding
Directives and pipesDirectives and pipes
Services and DIServices and DI
RoutingRouting
FormsTemplate-driven, Reactive
RxJSRxJS basics
HTTPHttpClient and API
AuthAuth, interceptors, guards
CapstoneAngular project

React — Track 12:

TopicRead
Fundamentals and JSXReact fundamentals
State and eventsState and events
HooksHooks and effects
FormsForms and validation
RoutingRouting
API callsAPI integration
AuthAuthentication
Shared stateState management
Styling and accessibilityStyling and accessibility
CapstoneReact project

Stage exercises

From the guided path syllabus, in whichever framework you chose:

Connect one frontend workflow. Build the fee receipt screen end to end: route with a payment id, service call, loading state, error states for 401, 404 and 500, and a printable layout.

Build reusable components. A ReceiptCard, a Spinner and an ErrorMessage used by more than one screen.

Create a validated form. The record-payment form, with client-side validation — and confirm the API still rejects an invalid payment sent from Postman.

Add the authentication flow. Sign in, store the token, attach it to every request, and redirect to the login page on a 401.

Debugging drills

Fix template or injection errors. Angular: remove a service from the providers and read the injector error. React: use a hook conditionally and read the rules-of-hooks error.

Inspect a failed network request. Call the API with an expired token, read the 401 in the Network tab, and confirm your interceptor or wrapper redirects rather than showing a blank screen.

Trace a state or Observable error. React: cause an infinite render loop by omitting the dependency array from useEffect. Angular: subscribe without unsubscribing and watch a request fire on every navigation.

Prove the guard is not security. Hide the receipt route behind a guard for the Student role, then call the endpoint directly from Postman with a Student's token. If it returns 200, the bug is in stage 5, not here.

Practice

  1. Choose a framework and work through its track in full, including the capstone.
  2. Rebuild the stage 6 receipt page as a component with routing.
  3. Implement loading, success and three distinct error states.
  4. Navigate between two receipts and confirm the data updates — then break the dependency and watch it not.
  5. Build the record-payment form with validation, then bypass it from Postman.
  6. Add a route guard for a role, then call the same endpoint directly and record what happens.
  7. Attach the token via an interceptor (Angular) or a fetch wrapper (React).
  8. Redirect to the login page on a 401 rather than rendering an empty page.
  9. Move the API base URL into environment configuration, and confirm the built bundle contains it.
  10. Run npm run build and npm run preview, and confirm the receipt still loads against the API.

Exercise 6 is the one that shows where control actually lives.

You can now

  • Build a routed, component-based frontend in your chosen framework
  • Handle loading, success and error for every request
  • Build validated forms
  • Attach a token and handle a 401 centrally
  • Say which parts of the frontend are security and which are interface

Review questions

  1. What do Angular and React have in common, concept for concept?
  2. Why is a route guard not a security control?
  3. What are the three states every API call has?
  4. Why is a VITE_-prefixed variable not a place for a secret?

Next: Git, debugging, and AI-assisted development