0

I've got a strange problem that I hope is just a simple fix on my end. The change detection in Angular is not working only in production.

I've built a fairly complex app using Angular 7 and ngrx as state management. There are 2 main modules that are lazy loaded base on the route. The change detection strategy is OnPush and 99% of the app follows a pattern of data comes from server via ngrx effects to stateful components that then push the data into "dummy" presentational components via async pipe. Example:

this.loading$ = this.store.pipe(
  select(selector.isLoading),
  takeUntil(this.unsubscribe$)
);
<app-loading [loading]="loading$ | async"></app-loading>

On ng serve and ng serve --prod everything works as expected and there are no issues. However after running ng build --prod and pushing the js files into our .net solution change detection ceases to work.

What do I mean by "ceases to work"? I mean it does not change any model or components unless a DOM event has taken place.

For example using the code shown as above there is a loading spinner that displays until data comes from the server. In production the spinner sits on the screen until you randomly click. Then the app refreshes and the data is displayed. This issue continues throughout the app. That is, this issue is not just happening there.

The app is loaded in an .cshtml file in a .Net solution like this:

<script type="text/javascript" src="runtime.js"></script>
<script type="text/javascript" src="polyfills.js"></script>
<script type="text/javascript" src="main.js"></script>

The lazy loaded modules are within the folder of the .cshtml file and are showing no errors so I must assume everything is wired up correctly.

Again this is only in the prod bundle. Not in dev or serve or prod mode serve.

s.Lawrenz
  • 302
  • 3
  • 17
  • This question needs clarification. To me it just sounds like you need to refresh your browser cache when you say "it's not detecting a change in prod". – Zze Aug 26 '19 at 22:27
  • Maybe this is aimed more at angular devs. Angular has a change detection life cycle. And everything works as expected when the dev environment is on but not when built and sent to the server. – s.Lawrenz Aug 26 '19 at 22:47
  • @Zze I've heavily updated the question to include as much information as I can. Hopefully that makes more sense. – s.Lawrenz Aug 27 '19 at 13:02

1 Answers1

1

This ended up being a very weird situation with the rxjs from operator.

The application uses signalR as the API between the client and server. Most of the interactions with the hub is a jquery promise. I used the from operator to return the data.

return from(this.proxy.invoke(...args));

This worked find in development for reasons I cannot figure out. But the observer would not complete in production so even though state would update, the view was still waiting for the observer to complete.

I updated the code to return an observable on connection.

private async performInvoke(...argu): Promise {
  return await this.proxy.invoke(...argu);
}

invoke(...argu): Observable<any> {
  return new Observable(o =>
    const pInvoke = async () => {
      o.next(await this.performInvoke(...argu));
      o.complete();
    }
}

I'm simplifying here so if you find this make sure to add try catches and other error protections.

s.Lawrenz
  • 302
  • 3
  • 17
  • Having same issue in production only, the change detections doesn't always trigger. The issue is intermittent and happens only in production build... Can you shed more light what other observations you had? – EGN Jan 25 '22 at 18:40