0

Confusing, right? Yeah, this is messing with my head.

I'm using Angular 6.0.3 and I have a top navigation bar with a search bar in it. The searchService only holds the searchQuery variable.

app.component.html

 <app-topbar [(menuOpened)]="opened"></app-topbar>

 <router-outlet *ngIf="!searchService.searchQuery"></router-outlet>

When the user types anything to the search bar, the router outlet disappears and a search results component shows at the end of the page (in the app.component.html, outside of the router-outlet) like in this section:

topbar.component.html

<app-search [(searchString)]="searchString" *ngIf="searchService.searchQuery"></app-search>

So this will show up. We're almost there. This page has a series of list components, which show cards that are clickable. Let's focus on one of them.

product-list.component.html

<div class="product-list">
    <div (click)="goToProduct(item)" *ngFor="let item of items; let i = index" class="prod-card col-6 col-lg-2">
        <app-product-card *ngIf="item.serial" [product]="item" [number]="item.serial"></app-product-card>
        <app-product-card *ngIf="!item.serial" [product]="item" [number]="i+1"></app-band-card>
    </div>
</div>

This baby works just fine, and the click does the following:

product-list.component.ts

 goToProduct(obj: Product) {
    this.router.navigate(["/products", obj.link]);
  }

So yeah, the router is being instantiated in the constructor, all is good. This works. Let's be clear here. This works just fine, but in one special condition, it doesn't.

When I'm in the product's page, lets say /products/1156, showing the data from product with id 1156, and I write in the search bar a keyword, the search component will show me a list os products, categories and other items as alternatives for search result. If I clich any other list's card (let's say I click on a category: Perfect! works as intended. BUT, If I'm in a product's page, search for a keyword and click on a product's name, thus invoking the goToProduct() method described above, I get the following error:

** ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'component' of null
TypeError: Cannot read property 'component' of null **
    at PreActivation.push../node_modules/@angular/router/fesm5/router.js.PreActivation.setupRouteGuards (router.js:2698)
    at router.js:2653
    at Array.forEach (<anonymous>)
    at PreActivation.push../node_modules/@angular/router/fesm5/router.js.PreActivation.setupChildRouteGuards (router.js:2652)
    at PreActivation.push../node_modules/@angular/router/fesm5/router.js.PreActivation.initialize (router.js:2617)
    at MapSubscriber.project (router.js:3999)
    at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:35)
    at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
    at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber.notifyNext (mergeMap.js:79)
    at InnerSubscriber.push../node_modules/rxjs/_esm5/internal/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:15)
    at resolvePromise (zone.js:814)
    at resolvePromise (zone.js:771)
    at zone.js:873
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:3751)
    at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:420)
    at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:500)
    at invokeTask (zone.js:1540)

This makes me think my app router has a problem, right? As it's trying to fetch a child component of my products page, or something that is currently null... will router.navigate try to navigate to a child component here? Yeah, but then again, why does this only occur when the component is already loaded? is this a onSameURLNavigation issue or something like that?

Keep in mind I'm using @angular/router version 6.0.3, so there's no onSameUrlNavigation: 'reload' on the routes' Extra Options (would this solve my problem, though? Upgrading the whole app now would be a hassle, but if it solves it... I'd do it)

And last but not least, my routes are pretty ok, like in:

const routes: Routes = [
  { path: '', component: HomePageComponent },
  { path: 'login', component: LoginComponent },
  { path: 'about', component: AboutComponent },
  { path: 'me', component: MyPageComponent },
  { path: 'my-profile', component: MyProfileComponent },
  { path: 'forgot', component: ForgotPasswordComponent },
  { path: 'categories', component: CategoryComponent },
  { path: 'products', component: ProductsComponent },
  { path: 'products/:id/:slug', component: ProductsComponent },
  ..........
  { path: '**', component: ErrorNotFoundComponent },

];

So I don't know where I could be going wrong here. Can you guys please help?

Thanks so much in advance!!

-- EDIT

TL;DR

My navigation does not work on a very specific situation: When I try to navigate from page a/:id1 to same page a, but a/:id2 AND I trigger the router.navigate() from a component that is outside of the <router-outlet> tag: my top nav bar's search results section. Other than this particular situation, it works fine...

Pstr
  • 777
  • 1
  • 8
  • 17
  • 1
    This is all a bit complex to work through. Is it possible to do a *very simple* sample in stackblitz that illustrates the problem? Also, have you seen this: https://stackoverflow.com/questions/44789867/uncaught-in-promise-typeerror-cannot-read-property-component-of-null Since you have an `ngIf` on your router outlet, this may be the case? – DeborahK Jan 26 '19 at 01:04
  • Hi, yes, it is.. I'll try to build up an example there.. the issue is: something works, then it doesn't. When I'm on the page, I can't seem to navigate to it with another ID through my search, which is out of the `router-outlet`. I can do it if I add buttons to the page, so it's black magic problem, you see... And yes, I've seen the question you put there, it's on child routes, it doesn't help me... unfortunately – Pstr Jan 26 '19 at 01:09
  • Read the second answer ... it is about using conditionals on (or around) the router outlet ... just like you have. – DeborahK Jan 26 '19 at 01:15
  • Hum... I don't think my problem is async... I have a ready url to navigate, I'm not waiting for any callbacks, it's failing to reload the same page with other (already fetched) parameter... I tried changing the scope of the router outlet on the divs, but it's no good. Keeps failing in this particular situation... My conditional makes the outlet go missing when search is used, and that's fine... so not the same situation, since it comes back once i click on something on the search results (the querystring is deleted when there's a router event) This brain teaser is good, thanks! More ideas? – Pstr Jan 26 '19 at 01:30

0 Answers0