universal: Engine setup error in argument type

Bug Report

What is the expected behavior?

Engine setup should work as expected

What is the current behavior?

Error in app.engine (), is it an issue with versions?

Argument of type ‘(filePath: string, options: RenderOptions, callback: (err?: Error | null | undefined, html?: string | undefined) => void) => void’ is not assignable to parameter of type ‘(path: string, options: object, callback: (e: any, rendered: string) => void) => void’. Types of parameters ‘callback’ and ‘callback’ are incompatible. Types of parameters ‘rendered’ and ‘html’ are incompatible. Type ‘string | undefined’ is not assignable to type ‘string’. Type ‘undefined’ is not assignable to type ‘string’.ts(2345)`

Preview of my server.ts

const app = express();
const PORT = process.env.PORT || 4001;
const DIST_FOLDER = join(process.cwd(), 'wwwroot', 'browser');
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./wwwroot/server/main');
//Error is here
app.engine(
  'html',
  ngExpressEngine({
    bootstrap: AppServerModuleNgFactory,
    providers: [provideModuleMap(LAZY_MODULE_MAP)]
  })
);
app.set('view engine', 'html');
app.set('views', DIST_FOLDER);

What modules are related to this issue?

- [ ] aspnetcore-engine
- [ ] common
- [x ] express-engine
- [ ] hapi-engine
- [ ] module-map-ngfactory-loader

Environment:

Output from: ng --version. Angular CLI: 7.0.6 Node: 8.14.0 OS: win32 x64 Angular: <error> … animations, cdk, cli, common, compiler, compiler-cli, core … flex-layout, forms, http, language-service, material … platform-browser, platform-browser-dynamic, platform-server … router, service-worker

Package Version

@angular-devkit/architect 0.10.6 (cli-only) @angular-devkit/build-angular <error> @angular-devkit/core 7.0.6 (cli-only) @angular-devkit/schematics 7.0.6 (cli-only) @schematics/angular 7.0.6 (cli-only) @schematics/update 0.10.6 (cli-only) rxjs 6.5.2 typescript 3.1.6 webpack 4.29.0

Preview of my package.json

 "dependencies": {
    "@angular/animations": "^7.1.4",
    "@angular/cdk": "^7.0.4",
    "@angular/common": "^7.0.4",
    "@angular/compiler": "^7.0.4",
    "@angular/core": "^7.0.4",
    "@angular/flex-layout": "^7.0.0-beta.24",
    "@angular/forms": "^7.0.4",
    "@angular/http": "^7.0.4",
    "@angular/material": "^7.0.4",
    "@angular/platform-browser": "^7.0.4",
    "@angular/platform-browser-dynamic": "^7.0.4",
    "@angular/platform-server": "^7.1.4",
    "@angular/router": "^7.0.4",
    "@angular/service-worker": "^7.0.4",
    "@netbasal/ngx-content-loader": "2.1.0",
    "@nguniversal/express-engine": "7.0.2",
    "@nguniversal/module-map-ngfactory-loader": "v7.0.2",
    "@ngx-translate/core": "11.0.1",
    "@ngx-translate/http-loader": "4.0.0",
  }

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 12
  • Comments: 17 (1 by maintainers)

Commits related to this issue

Most upvoted comments

@alan-agius4 here are the steps that reproduce the error using the Angular CLI and following the documentation for adding Angular Universal:

$ ng new TestAngularUniversal --defaults=true --strict=true
$ cd TestAngularUniversal
$ ng add @nguniversal/express-engine
$ npm run build:ssr && npm run serve:ssr

The relevant error output is:

ERROR in server.ts:18:25 - error TS2345: Argument of type '(filePath: string, options: Readonly<RenderOptions>, callback: (err?: Error | null | undefined, html?: string | undefined) => void) => void' is not assignable to parameter of type '(path: string, options: object, callback: (e: any, rendered: string) => void) => void'.
  Types of parameters 'callback' and 'callback' are incompatible.
    Types of parameters 'rendered' and 'html' are incompatible.
      Type 'string | undefined' is not assignable to type 'string'.
        Type 'undefined' is not assignable to type 'string'.

18   server.engine('html', ngExpressEngine({
                           ~~~~~~~~~~~~~~~~~
19     bootstrap: AppServerModule,
   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20   }));
   ~~~~

I also encountered this after upgrading to angular 9, my workaround is similar to @bufke .

  server.engine(
    'html',
    ngExpressEngine({
      bootstrap: AppServerModule
    }) as any
  );

hope there is a more elegant way.

Getting the same error after following pretty much same commands with same --strict=true flag. However, when I recreated the same project without the flag, the npm run build:ssr and npm run dev:ssr commands succeeded just fine. So seems to be something regarding the --strict=true flag and Angular 9?

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine) server.engine(‘html’, ngExpressEngine({ bootstrap: AppServerModule, }) as (path: string, options: object) => void);

Thank you @tuananhitoct, this solved my problem.

@bskeen @rts-cwalker I got the same error. It is strict mode when --strict flag is set. Fix to work arround:

export function app(): express.Application { // --> this function return server and must change return type to express.Application. this is explanation for last line of this function.
  const server: express.Application = express();
  const distFolder = join(process.cwd(), 'dist/PROJECT_NAME/browser');
  const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';

  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  server.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
  }) as (path: string, options: object) => void); // --> add here. because typeof engine function and return type ngExpressEngine is not match. reassign type for it

  server.set('view engine', 'html');
  server.set('views', distFolder);

  // Example Express Rest API endpoints
  // server.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get('*.*', express.static(distFolder, {
    maxAge: '1y'
  }));

  // All regular routes use the Universal engine
  server.get('*', (req, res) => {
    res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
  });

  return server;
}