Theory
Front end meets back end
You have an Angular registration form and an Express API. Now connect them: when a student submits the form, its data must travel to the server, be processed, and a response come back. This round trip is the beating heart of a full-stack app.
This lesson wires the two halves together: Angular posts the form's data as JSON, Express reads it from the request body and responds, and Angular handles the reply. Once you can do this cleanly, you can connect any form to any API. It brings units 1 and 2 together.
Theory
The round trip
Here is the full journey of a submitted registration:
1. The Angular form collects data as form.value (a plain object).
2. Angular's HttpClient sends it: http.post('/api/register', form.value) returns an Observable.
3. The data travels as JSON in the request body over HTTP.
4. Express, using the express.json() middleware, exposes it as req.body; the handler processes it (saves it, validates it) and replies with res.json(...).
5. Back in Angular, you subscribe to the Observable to receive the response and react (show a success message, navigate away).
Angular sends and subscribes; Express reads and responds.
Practical
Angular: post the form and handle the response
constructor(private http: HttpClient) {}
submit() {
if (this.form.invalid) { this.form.markAllAsTouched(); return; }
this.http.post('http://localhost:3000/api/register', this.form.value)
.subscribe({
next: (res) => console.log('Server said:', res), // success
error: (err) => console.error('Failed:', err), // failure
});
}
// form.value is sent as JSON; subscribe receives the server's JSON reply.Practical
Express: read the body and respond
app.use(express.json()); // so req.body is parsed from the JSON sent
app.post('/api/register', (req, res) => {
const registration = req.body; // the form.value Angular sent
// ...validate and save it (to MongoDB, next lesson)...
res.status(201).json({ message: 'Registered', data: registration });
});
// Angular's subscribe(next) receives this JSON response.This example runs in Gri-Learn on the web, where you can edit it and see the output.
Formula
The pieces that must line up
For the round trip to work, a few things must match. The Angular URL must point at the running Express server (the right host and port). Express must have express.json() enabled, or req.body will be undefined. Because the front end and API are on different origins, CORS must be enabled on the server (the previous lesson). And Angular must subscribe, an HttpClient Observable does nothing until subscribed.
Most 'my form does not reach the server' bugs are one of these four: wrong URL, missing express.json(), missing CORS, or forgetting to subscribe. Check them in that order.
Quiz
In Angular, you call this.http.post('/api/register', form.value) but nothing happens, no request is sent. What is the most likely cause?
- Express is too fast
- You did not subscribe to the returned Observable; HttpClient requests do not fire until subscribed
- form.value is always empty
- POST cannot send data
Show the answer
You did not subscribe to the returned Observable; HttpClient requests do not fire until subscribed
Angular's HttpClient methods return a cold Observable that does NOT send the request until you subscribe to it. If you call http.post(...) but never .subscribe(...), no request goes out, which matches the symptom exactly. Option A is nonsense; server speed does not stop a request from being sent. Option C is wrong: form.value holds the reactive form's data (unless the form truly is empty, which is a different issue), and in any case an empty body would still SEND a request. Option D is wrong: POST is precisely the method for sending data in the body. The classic gotcha: an HttpClient call only executes when subscribed, so always subscribe (or use the async pipe).
Think first
Why does JSON work so smoothly between Angular and Express?
The form data goes out as JSON and comes back as JSON, and both sides handle it easily. Why is JSON such a natural fit here? Then tap.
Show the answer
Because JSON is JavaScript's native data format, and both Angular (TypeScript, a superset of JavaScript) and Express (JavaScript on Node) speak it effortlessly, so data moves between them with almost no translation. JSON (JavaScript Object Notation) is literally modelled on JavaScript objects: { name: 'Riya', event: 'Robotics' } is both a JS object and valid JSON. On the Angular side, form.value is already a JS/TS object, and HttpClient serialises it to JSON automatically when you post it; on the Express side, the express.json() middleware parses the incoming JSON straight back into a JS object on req.body, ready to use. The response makes the same trip in reverse: res.json(...) serialises a JS object to JSON, and Angular deserialises it back into an object your subscribe callback receives. So across the whole round trip, you are essentially passing plain objects around, with JSON as the on-the-wire form, and neither side has to do awkward manual conversion. This is a major reason full-stack JavaScript feels so cohesive: the front end, the transport format, the back end, and even a JSON-friendly database like MongoDB all share the same shape of data. Contrast that with stacks where you must map between, say, Java objects and JSON and SQL rows by hand. Same data model end to end is what makes the Angular-Express connection so smooth. One shape of data, all the way through.
Summary
Key takeaways
- Connecting front end to back end: Angular posts form data as JSON, Express reads and responds, Angular handles the reply.
- Angular's HttpClient sends the request (http.post(url, form.value)) and returns an Observable.
- The data travels as JSON in the request body; Express exposes it as req.body via express.json().
- Express processes it and replies with res.json() and a status; Angular subscribes to receive the response.
- Four things must line up: correct URL, express.json() enabled, CORS enabled, and Angular subscribing.
- HttpClient requests do not fire until subscribed, a classic gotcha.
- Memory hook: Angular sends and subscribes, Express reads req.body and responds, JSON both ways.