NativeScript / nativescript-angular

Integrating NativeScript with Angular
http://docs.nativescript.org/angular/tutorial/ng-chapter-0
Apache License 2.0
1.21k stars 241 forks source link

Routing zone error with ngrx usage #1511

Open tsonevn opened 5 years ago

tsonevn commented 5 years ago

From @pnahtanoj on September 11, 2018 16:20

Did you verify this is a real problem by searching the [NativeScript Forum]

Indeed. I did look for a dupe, as well.

Tell us about the problem

When routing to a previously visited page (with and ngrx subscription), I'm getting a zone error

Which platform(s) does your issue occur on?

iOS

Please provide the following version numbers that your issue occurs with:

$ tns --version 4.1.2

"tns-core-modules": "~4.2.0",

"tns-ios": { "version": "4.1.1" }

Please tell us how to recreate the issue in as much detail as possible.

I had issues getting a ngrx integrated into playground, so I created a small application here: https://github.com/pnahtanoj/routing-error-example

You'll see the error if you got to Page1, then click Add One!

Is there code involved? If so, please share the minimal amount of code needed to recreate the problem.

See previous item

Copied from original issue: NativeScript/NativeScript#6257

pnahtanoj commented 5 years ago

Is there a reason this moved?

NickIliev commented 5 years ago

@pnahtanoj the issue is related to Angular routing so this is the appropriate repository to log it.

NickIliev commented 5 years ago

@pnahtanoj the error is non-blocking and the items are added as expected on my side. It also looks like an error related to the Angular logic

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. 

Previous value: 'items: [object Object]'. Current value: 'items: [object Object],[object Object],[object Object],[object Object]

Refer to this blog post for informati9on on how you could debug and find what is causing the issue

Basically, in your case, you n use the delay operator when piping

    this.items$ = this.store.select(selectItems)
      .pipe(
        delay(0), // HERE
        tap(_ => {
          console.log('HOME SELECT: ', _)
        }));
pnahtanoj commented 5 years ago

The examples in the post relate to sourcing data in AfterViewInit, which my example is not doing. The fetch call is in OnInit, which is the ultimate solution in that blog post.

I've used this pattern in a number of vanilla ng apps without having this type of timing issue, so I don't think we can call it an error with Angular logic.

FWIW, that error persists without the pipe, so 'using delay when piping' isn't a solution either.

pnahtanoj commented 5 years ago

Something else to consider. I updated the project to use the service directly (bypassing the state selector) for data sourcing here:

https://github.com/pnahtanoj/routing-error-example/commit/dcda9aa92d5d8118fd6d8c0037322d7c97ef68d6

This works without the delay workaround. Which leads me to believe that in the native context, ngrx selectors are adding enough overhead to create the timing issues, though I don't really understand why that would be the case.

pnahtanoj commented 5 years ago

Similary, moving the fetch into the constructor works:

https://github.com/pnahtanoj/routing-error-example/commit/7ec288bcbacc89c923635ff737b983c44773c41a

Which again seems to belie a timing issue.