43

I'm getting this error after upgrading to angular 9. I'm using visual studio 2019, ASP .NET core with angular. Even if I create new project and update angular to 9 version, It stops working.

Complete list of page response is :

TimeoutException: The Angular CLI process did not start listening for requests within the timeout period of 0 seconds. Check the log output for error information. Microsoft.AspNetCore.SpaServices.Extensions.Util.TaskTimeoutExtensions.WithTimeout(Task task, TimeSpan timeoutDelay, string message) Microsoft.AspNetCore.SpaServices.Extensions.Proxy.SpaProxy.PerformProxyRequest(HttpContext context, HttpClient httpClient, Task baseUriTask, CancellationToken applicationStoppingToken, bool proxy404s) Microsoft.AspNetCore.Builder.SpaProxyingExtensions+<>c__DisplayClass2_0+<b__0>d.MoveNext() Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

My package.json is:

{
  "name": "webapplication10",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "build:ssr": "ng run WebApplication10:server:dev",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "9.0.0",
    "@angular/cdk": "~9.0.0",
    "@angular/common": "9.0.0",
    "@angular/compiler": "9.0.0",
    "@angular/core": "9.0.0",
    "@angular/forms": "9.0.0",
    "@angular/material": "~9.0.0",
    "@angular/platform-browser": "9.0.0",
    "@angular/platform-browser-dynamic": "9.0.0",
    "@angular/platform-server": "9.0.0",
    "@angular/router": "9.0.0",
    "@nguniversal/module-map-ngfactory-loader": "8.1.1",
    "aspnet-prerendering": "^3.0.1",
    "bootstrap": "^4.4.1",
    "core-js": "^3.6.4",
    "jquery": "3.4.1",
    "oidc-client": "^1.10.1",
    "popper.js": "^1.16.1",
    "rxjs": "^6.5.4",
    "tslib": "^1.10.0",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "^0.900.1",
    "@angular/cli": "9.0.1",
    "@angular/compiler-cli": "9.0.0",
    "@angular/language-service": "9.0.0",
    "@types/jasmine": "^3.5.3",
    "@types/jasminewd2": "~2.0.8",
    "@types/node": "^12.12.27",
    "codelyzer": "^5.2.1",
    "jasmine-core": "~3.5.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "^4.4.1",
    "karma-chrome-launcher": "~3.1.0",
    "karma-coverage-istanbul-reporter": "^2.1.1",
    "karma-jasmine": "~3.1.1",
    "karma-jasmine-html-reporter": "^1.5.2",
    "typescript": "3.7.5"
  },
  "optionalDependencies": {
    "node-sass": "^4.12.0",
    "protractor": "~5.4.2",
    "ts-node": "~8.4.1",
    "tslint": "~5.20.0"
  }
}
```
Khizar Murad
  • 621
  • 2
  • 7
  • 15

22 Answers22

47

TL;DR

Sadly the issue seems related to some changes in the way Angular CLI starts up the angular part of the application. As per this issue:

https://github.com/dotnet/aspnetcore/issues/17277

proposed solutions are to set progress: true in angular.json or perform a simple echo prior to ng serve (https://github.com/dotnet/aspnetcore/issues/17277#issuecomment-562433864).

Full answer

I dug the asp.net core code base (https://github.com/dotnet/aspnetcore), looking how the Angular template starts up the Angular application.

The core engine that starts up the angular server is represented by two classes: AngularCliMiddleware (https://git.io/JvlaL) and NodeScriptRunner (https://git.io/Jvlaq).

In AngularCliMiddleware we find this code (I removed the original comments and added some of my own to explain a couple of things):

public static void Attach(ISpaBuilder spaBuilder, string npmScriptName)
{
    var sourcePath = spaBuilder.Options.SourcePath;
    if (string.IsNullOrEmpty(sourcePath))
    {
        throw new ArgumentException("Cannot be null or empty", nameof(sourcePath));
    }

    if (string.IsNullOrEmpty(npmScriptName))
    {
        throw new ArgumentException("Cannot be null or empty", nameof(npmScriptName));
    }

    // Start Angular CLI and attach to middleware pipeline
    var appBuilder = spaBuilder.ApplicationBuilder;
    var logger = LoggerFinder.GetOrCreateLogger(appBuilder, LogCategoryName);
    var angularCliServerInfoTask = StartAngularCliServerAsync(sourcePath, npmScriptName, logger);

    var targetUriTask = angularCliServerInfoTask.ContinueWith(
        task => new UriBuilder("http", "localhost", task.Result.Port).Uri);

    SpaProxyingExtensions.UseProxyToSpaDevelopmentServer(spaBuilder, () =>
    {
        var timeout = spaBuilder.Options.StartupTimeout;
        return targetUriTask.WithTimeout(timeout,
            $"The Angular CLI process did not start listening for requests " +

            // === NOTE THIS LINE, THAT CARRIES THE "0 seconds" BUG!!!
            $"within the timeout period of {timeout.Seconds} seconds. " + 

            $"Check the log output for error information.");
    });
}

private static async Task<AngularCliServerInfo> StartAngularCliServerAsync(
    string sourcePath, string npmScriptName, ILogger logger)
{
    var portNumber = TcpPortFinder.FindAvailablePort();
    logger.LogInformation($"Starting @angular/cli on port {portNumber}...");

    var npmScriptRunner = new NpmScriptRunner(
        sourcePath, npmScriptName, $"--port {portNumber}", null);
    npmScriptRunner.AttachToLogger(logger);

    Match openBrowserLine;
    using (var stdErrReader = new EventedStreamStringReader(npmScriptRunner.StdErr))
    {
        try
        {
            // THIS LINE: awaits for the angular server to output
            // the 'open your browser...' string to stdout stream
            openBrowserLine = await npmScriptRunner.StdOut.WaitForMatch(
                new Regex("open your browser on (http\\S+)", RegexOptions.None, RegexMatchTimeout));
        }
        catch (EndOfStreamException ex)
        {
            throw new InvalidOperationException(
                $"The NPM script '{npmScriptName}' exited without indicating that the " +
                $"Angular CLI was listening for requests. The error output was: " +
                $"{stdErrReader.ReadAsString()}", ex);
        }
    }

    var uri = new Uri(openBrowserLine.Groups[1].Value);
    var serverInfo = new AngularCliServerInfo { Port = uri.Port };

    await WaitForAngularCliServerToAcceptRequests(uri);

    return serverInfo;
}

As you can see, the StartAngularCliServerAsync method creates a new NpmScriptRunner object, that is a wrapper around a Process.Start method call, basically, attaches the logger and then waits for the StdOut of the process to emit something that matches "open your browser on httpSOMETHING...".

Fun thing is this should work!

If you run ng serve (or npm run start) in ClientApp folder, once the server starts it still emit the output "open your browser on http...".

If you dotnet run the application, the node server actually starts, just enable all the logs in Debug mode, find the "Starting @angular/cli on port ..." line and try visiting localhost on that port, you'll see that your angular application IS running.

Problem is that for some reason the StdOut is not getting the "open your browser on" line anymore, nor it is written by the logger... it seems that in some way that particular output line from ng serve is held back, like it's no longer sent in the Stardard Output stream. The WaitForMatch method hits his timeout after 5 seconds and is catched from the code of the WithTimeout extension method, that outputs the (bugged) "... 0 seconds ..." message.

For what I could see, once you dotnet run your application, a series of processes is spawn in sequence, but i couldn't notice any difference in the command lines from Angular 8 to Angular 9.

My theory is that something has been changed in Angular CLI that prevents that line to be sent in stdout, so the .net proxy doesn't catch it and can't detect when the angular server is started.

As per this issue:

https://github.com/dotnet/aspnetcore/issues/17277

proposed solutions are to set progress: true in angular.json or perform a simple echo prior to ng serve (https://github.com/dotnet/aspnetcore/issues/17277#issuecomment-562433864).

Milo
  • 3,365
  • 9
  • 30
  • 44
Claudio Valerio
  • 2,302
  • 14
  • 24
  • Thanks for digging into issue Claudio, Yes It works when we change progress false to true so does ng serve, then It gives me "Uncaught SyntaxError: Strict mode code may not include a with statement" and to avoid this error As Fairlie Agile Suggest a solution that I have to remove line "export { renderModule, renderModuleFactory } from '@angular/platform-server';" From main.ts , – Khizar Murad Feb 15 '20 at 18:34
  • 1
    Also the progress solution works randomly. So I guess, neither of them work. – Gerardo Buenrostro González Feb 18 '20 at 15:19
  • 1
    @GerardoBuenrostroGonzález you could try this solution: https://github.com/dotnet/aspnetcore/issues/17277#issuecomment-562236635. It's a little more hacky, but should work, basically by forcing another "open your browser..." line into the stdout. If neither this is working, please partecipate in the github discussion, adding more info to the case is always useful to achieve full fixing. Good luck! – Claudio Valerio Feb 18 '20 at 20:52
  • @ClaudioValerio Thanks! That DID work! A little bit overkill perhaps, but i'm not complaining! – Gerardo Buenrostro González Feb 19 '20 at 19:36
  • Here's a gihub repo that uses the package.json "start" version of the fix. https://github.com/jefflomax/dotnet-core-3-angular-9-ngrx-9 – AUSTX_RJL Apr 05 '20 at 16:46
  • 1
    This solution did not work for me the Angular version 9 I am using already has progress=true, I am testing on localhost, not sure if this is an only dev environment issue – Naga Oct 28 '20 at 09:44
  • @ClaudioValerio This is one of the best answers that I have read on SO. Thanks – Chris Phillips Jan 15 '21 at 23:04
  • 1
    For those like me, whose problem didn't get solved, you can try this also: (in package.json) `"start": "echo Starting... && ng serve --host 0.0.0.0"` took from github: https://github.com/dotnet/aspnetcore/issues/22883 – turanszkik Apr 12 '21 at 13:12
34

I resolved it by changing:

"scripts": {   
        "start": "ng serve",

to:

 "scripts": {   
        "start": "echo Starting... && ng serve",

in package.json

opp
  • 1,010
  • 10
  • 17
  • This solution worked for me. I was facing this issue for days and nothing was working. – Rajashree Pethkar Aug 02 '20 at 13:55
  • This resolves my issue too but think was because I had the global CLI version different from the local one and the warnings and so are taking some time. By adding the echo helps to create the necessary delay. I update the CLI and it works without the workaround. – Ray Aug 20 '20 at 16:52
  • I upvoted this but however, this workaround does not seem to be consistent – Naga Oct 28 '20 at 09:45
11

Here is a workaround:

  • In package.json change the start-script from "ng serve" to "ngserve"
"scripts": {
  "start": "ngserve",
  • In the same directory create a file ngserve.cmd with the following content:
@echo ** Angular Live Development Server is listening on localhost:%~2, open your browser on http://localhost:%~2/ **
ng serve %1 %~2

Now Dotnet gets the line it is waiting for. After that the command ng serve will start the server (so in fact the Angular Live Development Server is not yet listening), the browser will open, and first it won't work (ng serve still compiling), but if you press reload after a while, it should be fine.

This is just a workaround, but it works for us.

bttb
  • 121
  • 1
  • 2
10

Here is what I did

from Fairlie Agile, commented out this line in main.ts

export { renderModule, renderModuleFactory } from '@angular/platform-server';

From Claudio Valerio In angular.json , set

"progress": true,

Now I can run the app by clicking on F5 / Run IIS Express

freddoo
  • 6,770
  • 2
  • 29
  • 39
8

As suggested in https://developercommunity.visualstudio.com/solutions/446713/view.html, you should setup the StartupTimeout configuration setting.

Basically in Startup.cs:

 app.UseSpa(spa =>
    {
      spa.Options.SourcePath = "./";
      //Configure the timeout to 5 minutes to avoid "The Angular CLI process did not start listening for requests within the timeout period of 50 seconds." issue
      spa.Options.StartupTimeout = new TimeSpan(0, 5, 0);
      if (env.IsDevelopment())
      {
        spa.UseAngularCliServer(npmScript: "start");
      }
    });
Claudio Valerio
  • 2,302
  • 14
  • 24
  • 1
    Yes I've tried this again getting same error. My error is little bit different from your suggestion as it shows **timeout period of 0 seconds.** – Khizar Murad Feb 12 '20 at 14:19
  • Seems the SPA middleware is getting a StartupTimeout of 0 seconds from somewhere. Since the default should be 120 seconds (ref: https://github.com/dotnet/aspnetcore/blob/116799fa709ff003781368b578e4efe2fa32e937/src/Middleware/SpaServices.Extensions/src/SpaOptions.cs) it is plausible that somewhere is told to timeout to 0 secs. Check also your appSettings.json for "SpaOptions" (also check any environment specific setting file and variables). Can you post your Startup.cs (clean up from irrelevant/proprietary code) and appSettings.json? – Claudio Valerio Feb 12 '20 at 15:16
  • Also: if you "ng serve" your client application from a console, is it running without issues? – Claudio Valerio Feb 12 '20 at 15:17
  • if I run ng server then browser only show me loading page with console error : Uncaught SyntaxError: Strict mode code may not include a with statement. – Khizar Murad Feb 12 '20 at 15:57
  • I investigated more on the subject. I've created 2 identical Angular applications and updated the Angular version in just one of them. The updated one does not function and the timeout message is shown exactly as in your case. I think something is preventing the .net proxy to communicate with the Angular server (that is running correctly). – Claudio Valerio Feb 14 '20 at 15:05
  • BTW: that "0 seconds" message is due to a bug in asp.net core <=3.1.1. It's fixed on the master branch, so I think they'll have it patched on the next sdk release...? – Claudio Valerio Feb 14 '20 at 15:34
  • So this bug is known to them will be fixed? – Khizar Murad Feb 15 '20 at 18:35
  • 1
    Yes, the issue 17277 is included in the "Next sprint planning" milestone (https://git.io/Jv85b) which, and I quote: "is used to track the issues we plan to consider taking as part of our next milestone, within current release.", so the fix of this bug in one of the next releases is at least possible. – Claudio Valerio Feb 17 '20 at 10:50
7

I added verbosity to the serving process in the file package.json like this.

"scripts": {
  "ng": "ng",
  "start": "ng serve --verbose",
  "build": "ng build", ...
}, ...

No idea why it worked but I sense it somehow relates to causing the same slowdown as echo does.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Konrad Viltersten
  • 36,151
  • 76
  • 250
  • 438
5

to resolve the strict mode error remove this line from main.ts

export { renderModule, renderModuleFactory } from '@angular/platform-server';

This doesn't resolve the timeout issue however. I am also getting this error after upgrading to Angular 9 and using .NET core.

Running the angular app using "ng serve" and then changing your startup spa script to use UseProxyToSpaDevelopmentServer works as a work-around

Fairlie Agile
  • 268
  • 2
  • 6
5

I have changed in use spa pipeline configuration in configure method of startup class, It works for me.

app.UseSpa(spa =>
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501
                spa.Options.StartupTimeout = new System.TimeSpan(0, 15, 0);
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
  • works. in addition, we may use the asp project as web api without hosting angular and the front end dev using vs code. but need to put in the environment file the base url of the web api. – Ashraf Sayied-Ahmad Feb 15 '22 at 09:30
4

If you are doing backend work only, in your startup.cs comment out

spa.UseAngularCliServer(npmScript: "start");

and add

spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");

Like so...

//spa.UseAngularCliServer(npmScript: "start");
spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");//Todo Switch back for SPA Dev

Run the SPA from cmd (in ClientApp Directory) via npm start.

Then when your run or debug your full app from Visual Studio, it will spin up so much faster.

Milo
  • 3,365
  • 9
  • 30
  • 44
Mark Naber
  • 63
  • 2
  • 12
3

In package.json change ng serve to ng serve --host 0.0.0.0 enter image description here

Dacili
  • 258
  • 4
  • 8
2

Change to .NET5 solves my problem. You can also try this:

 "scripts": {   
    "start": "echo start && ng serve",

or

"start": "ng serve --port 0000",

in package.json

Xia
  • 159
  • 10
1

In my case there were TypeScript compile errors that were not caught by SpaServices or ts-node. There were references using the same file name with different namespaces that confused the runtime compiler. Execute ng build in the ClientApp folder and make sure there are no errors.

manit
  • 604
  • 7
  • 11
1

None of the solutions here worked for me. The problem began after I upgrade components of my solution to their last versions. The only thing that works for me is to upgrade my global angular cli to have same version as my local one :

npm uninstall -g angular-cli
npm cache clean
npm cache verify
npm install -g @angular/cli@latest
Kevin.Debeil
  • 349
  • 3
  • 8
1

run npm install -g @angular/cli from command prompt

Nguyễn Văn Phong
  • 13,506
  • 17
  • 39
  • 56
1
"scripts": {
    "ng": "ng",
    "start": **"ng serve --port 33719 --open",**
    "build": "ng build",

Use the setting present in bold font in package.json

Nguyễn Văn Phong
  • 13,506
  • 17
  • 39
  • 56
1

I ran into a similar issue and I made the following updates in the package.json file

"scripts": {
    "ng": "ng",
    "start": "echo hello && ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
}

See github resolution in [dotnet/angular - issues/17277]

Josef
  • 2,869
  • 2
  • 22
  • 23
Jean-Joseph
  • 109
  • 1
  • 5
0

For development purpose if you are getting the error as 'TimeoutException: The Angular CLI process did not start listening for requests within the timeout period of 0 seconds.' .

Please follow these 2 steps which work for me as well :

In command prompt, Run the 'ng serve' command to run the angular solution. In startup.cs file, change the start up timeout to minutes. even it will not take that much of time as angular solution is already running. -> spa.Options.StartupTimeout = new TimeSpan(0, 5, 0);

Please mark the answer if it helps you !!

Thanks.

0

I did all of these successful suggestions. But the timeout issue was still there. In my case the following worked for me, (Will attach all the steps)

  1. Comment the following line in main.ts to fix the strict mode issue

    export { renderModule, renderModuleFactory } from '@angular/platform-server';

  2. Change ng serve to echo Starting && ng serve in the package.json file

  3. Just ran ng serve command manually using the Node.js Command Prompt. Then attempt to run the project in Visual Studio.

Indika
  • 188
  • 1
  • 9
0

I received this error after my Visual Studio crashed while debugging. I couldn't make it go away using any of the above solutions. Eventually I deleted my project and cloned the code from the source. After that it loaded up just fine.

Nacht
  • 3,342
  • 4
  • 26
  • 41
0

This was what worked for me:

In angular.json file,

I set

progress:true

Then run the app in visual studio 2019

I.Ray
  • 1
0

None of the above worked consistently for me.

I experienced this even after upgrading to Angular 14 and net7.0. My symptoms were it would load fine the first couple of runs but then start to get bogged down after the app was stopped/run multiple times in one session.

I checked task manager and noticed multiple Node.js JavaScript Runtime processes piling up. Once I Ended those tasks, running the project from Visual Studio went back to normal and started up without issue.

Milo
  • 3,365
  • 9
  • 30
  • 44
-1

The best approach is to insert this line at Startup

spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");

And then run or debug your app from Visual Studio.