Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular 17 with SSR injection server response is null, when you use response.status. ERROR: Cannot read properties of null (reading 'status') #53810

Closed
hittten opened this issue Jan 5, 2024 · 2 comments

Comments

@hittten
Copy link

hittten commented Jan 5, 2024

Which @angular/* package(s) are the source of the bug?

platform-server, Don't known / other

Is this a regression?

Yes

Description

Indeed, several things about SSR need to be documented, for example since the move from @nguniversal/express-engine to @angular/ssr the express tokens were lost:

https://github.com/angular/universal/blob/e798d256de5e4377b704e63d993dc56ea35df97d/modules/express-engine/tokens/injection-tokens.ts

I had to search the internet for a while to understand that I had to add the "src/express.tokens.ts" file now because it no longer comes in the @angular/ssr package and that's what I did

I have published a repo with the minimum to recreate the SSR problem with angular 17: https://github.com/hittten/angularSSR17

Clone & Setup:

git clone https://github.com/hittten/angularSSR17
npm install
npm start

Log

Navigate to http://localhost:4200/404

ERROR TypeError: Cannot read properties of null (reading 'status')
    at _NotFoundPageComponent (/Workspace/hittten/angularSSR17/src/app/pages/not-found-page/not-found-page.component.ts:17:21)

Angular 16 code (working):

import {RESPONSE} from "@nguniversal/express-engine/tokens";
import {Response} from "express";

constructor(
    @Optional() @Inject(RESPONSE) private response: Response,
    @Inject(PLATFORM_ID) private platformId: object,
  ) {
    if (isPlatformServer(this.platformId)) {
      this.response.status(404)
    } else {
      console.error(`response status code 404`)
    }
  }

Angular 17 code (not working):

import { InjectionToken } from '@angular/core';
import { Request, Response } from 'express';

const REQUEST = new InjectionToken<Request>('REQUEST');
const RESPONSE = new InjectionToken<Response>('RESPONSE');

constructor(
    @Optional() @Inject(RESPONSE) private response: Response,
    @Inject(PLATFORM_ID) private platformId: object,
  ) {
    if (isPlatformServer(this.platformId)) {
      this.response.status(404)
    } else {
      console.error(`response status code 404`)
    }
  }

Info

basically I have created a project like this:

npx @angular/cli@17.0.8 new angularSSR17 --ssr --routing --scss --skip-tests
cd angularSSR17
npm i -D firebase-tools@13.0.2
ng g c pages/homePage
ng g c pages/aboutPage
ng g c pages/notFoundPage

I also disable pre-render in angular.json:

{
    "scripts": [],
    "server": "src/main.server.ts",
    "prerender": false,
    "ssr": {
      "entry": "server.ts"
    }
}

and I have done the settings of the routes for lazy load. I have not installed @angular/fire because it is not necessary to recreate the SSR error.

Please provide a link to a minimal reproduction of the bug

https://github.com/hittten/angularSSR17

Please provide the exception or error you saw

No response

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 17.0.8
Node: 20.10.0
Package Manager: npm 10.2.5
OS: darwin arm64

Angular: 17.0.8
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, platform-server
... router, ssr

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1700.8
@angular-devkit/build-angular   17.0.8
@angular-devkit/core            17.0.8
@angular-devkit/schematics      17.0.8
@schematics/angular             17.0.8
rxjs                            7.8.1
typescript                      5.2.2
zone.js                         0.14.2

Anything else?

I also intent to provide express tokens in /server.ts: provide: REQUEST, useValue: req }, { provide: RESPONSE, useValue: res }, which is not necessary to do in angular 16, but it doesn't work either.

  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 },
          { provide: REQUEST, useValue: req },
          { provide: RESPONSE, useValue: res },
        ],
      })
      .then((html) => res.send(html))
      .catch((err) => next(err));
  });
@JeanMeche
Copy link
Member

Hi, this issue is being tracked on the CLI repo angular/angular-cli#26323

@JeanMeche JeanMeche closed this as not planned Won't fix, can't repro, duplicate, stale Jan 5, 2024
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Feb 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants