This document explains, in detail, how the Angular application boots, renders the page, and exchanges data with the Express backend when you submit the registration form.
1. Development Environment Startup
1.1 Backend
- Run
npm run serverinexamples/week03-04/. server.jsstarts an Express app onhttp://localhost:4000: - Appliescors()andexpress.json(). - RegistersPOST /api/contactthat logs the payload and returns a JSON response with the echoed fields.
1.2 Frontend
- Run
npm start(alias forng serve). - Angular CLI reads
angular.json: -build.options.browser→src/main.ts(entry point). -build.options.polyfills→zone.js. -serve.options.proxyConfig→proxy.conf.json(proxy/apitohttp://localhost:4000). - Dev server compiles TypeScript, serves bundles, and enables hot module replacement.
2. Browser Boot Sequence
- The dev server serves
src/index.html. It contains only<app-root></app-root>in the body. - Bundled JavaScript loads and executes
src/main.ts:ts bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err)); appConfig(src/app/app.config.ts) registers providers: -provideZoneChangeDetection({ eventCoalescing: true })-provideRouter(routes)(routes defined insrc/app/app.routes.ts) -provideHttpClient(withFetch())(enables HTTP requests)- Angular creates the root injector, sets up zone.js patches, and instantiates
AppComponent.
3. Rendering the UI
AppComponent(src/app/app.component.ts) is a standalone component with template<router-outlet />.- Router resolves routes from
app.routes.ts:ts export const routes: Routes = [ { path: '', component: FormSandboxComponent }, ]; - Angular creates
FormSandboxComponent(src/app/examples/form-sandbox.component.ts) and renders its template: - AppliesHighlightDirectiveandIfViewportDirective. - Displays an informational aside and the<app-registration-form>component. RegistrationFormComponent(src/app/examples/registration-form.component.ts): - Standalone component importingCommonModuleandReactiveFormsModule. - Builds a reactive form with fields:name,email,role,newsletter,password,confirmPassword. - Uses Angular signals to managesubmitting,result, anderrorstate. - Template renders the form, validation messages, submit button, and the backend response section.- Change detection keeps the UI in sync with form values and signal updates.
4. Submitting the Form
4.1 Collecting & Validating Data
submit()inRegistrationFormComponentruns on form submission: 1. If the form is invalid,markAllAsTouched()exposes validation errors. 2. Extracts values usingthis.form.getRawValue()and removesconfirmPasswordfrom the payload. 3. Setssubmittingtotrueand clears previous errors.
4.2 Sending the Request
ApiService.submitRegistration(payload)executes:ts return this.http.post<RegistrationResponse>(`${this.baseUrl}/contact`, payload);API_BASE_URLdefaults to/api, so the request URL becomes/api/contact.- Because
proxy.conf.jsonmaps/api→http://localhost:4000, Angular CLI forwards the request to the Express server.
4.3 Backend Processing
- Express route (
server.js):js app.post('/api/contact', (req, res) => { const data = req.body ?? {}; console.log('📩 Registration received:', data); res.json({ message: 'Registration payload received by backend.', receivedAt: new Date().toISOString(), data, }); }); - Logs the payload in the terminal.
- Responds with JSON containing
message,receivedAt, anddata(the submitted fields).
4.4 Handling the Response on the Frontend
- The RxJS
subscribeinsubmit()handles success and error paths:ts this.api.submitRegistration(payload).subscribe({ next: (response) => { this.submitting.set(false); this.result.set(response); this.form.reset({ role: 'developer', newsletter: false, password: '', confirmPassword: '' }); }, error: () => { this.submitting.set(false); this.error.set('Unable to reach the server. Please try again.'); }, }); - On success:
submitting→falseresultsignal stores the echoed data- Form resets to defaults
- On failure (e.g., backend not running):
submitting→falseerrorsignal displays a message under the form
4.5 Rendering the Response
- Template shows results when
result()is truthy: ```html
Backend Response
{{ result()?.message }}
- Name: {{ result()?.data?.name ?? '—' }}
- Email: {{ result()?.data?.email ?? '—' }}
- Role: {{ result()?.data?.role ?? '—' }}
- Newsletter: {{ result()?.data?.newsletter ? 'Yes' : 'No' }}
- Password: {{ result()?.data?.password ?? '—' }}
- Received At: {{ result()?.receivedAt | date:'medium' }}
``
-error()` signal renders an error paragraph when the backend is unreachable.
5. End-to-End Summary
- Startup: Backend and Angular dev server run in parallel.
- Bootstrap: Browser loads
index.html, executesmain.ts, and renders routing hierarchy down toRegistrationFormComponent. - User Input: Reactive form enforces validations and exposes
submit(). - Request:
ApiServiceposts JSON to/api/contact; Angular CLI proxies to Express. - Backend Response: Express logs, echoes payload, and returns response JSON.
- Frontend Update: Response stored in a signal → UI shows the echoed field values; errors are surfaced if the request fails.
With both processes running (npm run server and npm start), clicking Create Account will display the submitted data in the app and print it in the backend terminal.