angularangular-ssrangular18

How to add a POST method in Angular SSR - Server?


I am trying to make some tries with the new "@angular/ssr": "^18.0.4", what I want to archieve is to create a custom login logics on the server side, and then post the data to it from Angular.

I have add the use of my auth routing like this in server.ts:

  // Parse JSON bodies
  server.use(express.json());

  // Use auth routes
  server.use('/api', authRoutes);
  
  // Serve static files from /browser
  server.get('**', express.static(browserDistFolder, {
    maxAge: '1y',
    index: 'index.html',
  }));

  // All regular routes use the Angular engine
  server.get('**', (req, res, next) => {
    const { protocol, originalUrl, baseUrl, headers } = req;

    commonEngine
      .render({
        bootstrap,
        documentFilePath: indexHtml,
        url: `${protocol}://${headers.host}${originalUrl}`,
        publicPath: browserDistFolder,
        providers: [
          { provide: APP_BASE_HREF, useValue: baseUrl }
        ],
      })
      .then((html) => res.send(html))
      .catch((err) => next(err));
  });

  return server;
}

The auth.routes looks like this:

import { Router } from 'express';
import { login } from './auth.controller';

const router = Router();

router.post('/login', login);

export default router;

Then I try to call the API like that in Angular:

  async loginWithCredential(credential: Credential): Promise<void> {
    try {
      const session: Session = await fetch('/api/login', {
        method: 'POST',
        body: JSON.stringify(credential)
      }).then(res => res.json());

      if (session) {
        this.redirectToUrl(session);
        return;
      }

      throw new Error("User not found!");
    } catch (error: any) {
      throw new Error(error.message);
    }
  }

But it seems that Angualr still tries to manage the /api/ routing by itself instead of managing it via Express as I get this error:

ERROR RuntimeError: NG04002: Cannot match any routes. URL Segment: 'api/login' at Recognizer.noMatchError (e:/GitHub/GAB-Auth/node_modules/@angular/router/fesm2022/router.mjs:3774:12) at eval (e:/GitHub/GAB-Auth/node_modules/@angular/router/fesm2022/router.mjs:3813:20) at eval (e:/GitHub/GAB-Auth/node_modules/rxjs/dist/esm/internal/operators/catchError.js:10:39) at OperatorSubscriber.OperatorSubscriber._error (e:/GitHub/GAB-Auth/node_modules/rxjs/dist/esm/internal/operators/OperatorSubscriber.js:23:21) at OperatorSubscriber.error (e:/GitHub/GAB-Auth/node_modules/rxjs/dist/esm/internal/Subscriber.js:40:18) at OperatorSubscriber._error (e:/GitHub/GAB-Auth/node_modules/rxjs/dist/esm/internal/Subscriber.js:64:30) at OperatorSubscriber.error (e:/GitHub/GAB-Auth/node_modules/rxjs/dist/esm/internal/Subscriber.js:40:18) at OperatorSubscriber._error (e:/GitHub/GAB-Auth/node_modules/rxjs/dist/esm/internal/Subscriber.js:64:30) at OperatorSubscriber.error (e:/GitHub/GAB-Auth/node_modules/rxjs/dist/esm/internal/Subscriber.js:40:18) at OperatorSubscriber._error (e:/GitHub/GAB-Auth/node_modules/rxjs/dist/esm/internal/Subscriber.js:64:30) { code: 4002 } 11:23:11 [vite] Pre-transform error: Failed to load url /api/polyfills.js (resolved id: /api/polyfills.js). Does the file exist? 11:23:11 [vite] Pre-transform error: Failed to load url /api/main.js (resolved id: /api/main.js). Does the file exist?


Solution

  • As mentioned in this issue on GitHub, using the ng serve ignores the server.ts so to run the SSR I needed to run those commands in two separate terminals:

    npm run watch

    and

    npm run serve:ssr:projectName