isaacplmann / ngx-tour

Product Tour Built in Angular
https://isaacplmann.github.io/ngx-tour
MIT License
246 stars 100 forks source link

Getting error "Can't attach to unregistered anchor with id filter" #76

Closed ranga-sriram closed 6 years ago

ranga-sriram commented 6 years ago

Hi, I tried the steps mentioned in https://github.com/isaacplmann/ngx-tour/issues/32

The project builds fine but the walkthrough box does not comes up. The console error reads:

Can't attach to unregistered anchor with id filter

where 'filter' is the name that I assigned to the html element using attribute tourAnchor="filter"

Would you know why this error comes up?

isaacplmann commented 6 years ago

One reason this could happen is if you TourMdMenuModule.forRoot() imported in both your AppModule and the lazy loaded module where the anchor is registered. This would create two separate instances of the TourService and the root TourService wouldn't know about the anchors registered on the lazy loaded TourService.

To fix that, make sure the AppModule has TourMdMenuModule.forRoot() and the lazy loaded module has TourMdMenuModule without the forRoot() part.

Another possible problem is that you're starting the tour before the tourAnchor directive has registered itself with the TourService. You could try delaying starting the tour.

ranga-sriram commented 6 years ago

Thanks for your reply @isaacplmann. I have actually the following in my code:

//app.module.ts
import { TourNgxBootstrapModule, TourService } from 'ngx-tour-ngx-bootstrap';
@NgModule({
  imports: [
    TourNgxBootstrapModule.forRoot()
  ]

Previously I did't include TourNgxBootstrapModule in any of my lazy loaded modules. But even when I try to include it without .forRoot() the same error comes up.

Regarding the second suggestion of delaying starting the tour, I tried a 2 second delay using settimeout() in the component where I use tourAnchor, but I get the same error:

setTimeout(() => {
      this.tourService.start();
    }, 2000);

Would you know if there is something else that I am missing?

isaacplmann commented 6 years ago

You can get some more debug information by doing this:

this.tourService.events$.subscribe(x => console.log(x));

You should see your anchor being registered before the start event happens.

ranga-sriram commented 6 years ago

Thanks for the help @isaacplmann. Your suggestions did get it to work. As mentioned in my previous comment I had to import TourNgxBootstrapModule in my lazy loaded module as well. Then with setTimeout of 2 seconds the pop-up works. I guess in your tutorial the tour begins when someone clicks a button and hence the elements with tourAnchor get enough time to be registered. Whereas in my case I wanted the tour to start as soon as the component is rendered. I tried this.tourService.start(); from various methods: constructor(), ngOnInit(), ngAfterViewInit(), but I eventually had to call it with setTimeout within ngOnInit(). I assumed that ngAfterViewInit() should at least work but it didn't. It would be nice to know when exactly a user can fire this.tourService.start() instead of randomly calling it within a setTimeout(). Would you have any suggestions?

Also, I would like to thank you for this beautiful plugin and your prompt support. I'm happy to give the package a star.

isaacplmann commented 6 years ago

If you want to be certain that the step is registered before you start the tour, you can subscribe to this.tourService.anchorRegistered$ and start the tour once the anchor with the id you want has registered itself.

On Jan 20, 2018 1:57 AM, "ranga-sriram" notifications@github.com wrote:

Thanks for the help @isaacplmann https://github.com/isaacplmann. Your suggestions did get it to work. As mentioned in my previous comment I had to import TourNgxBootstrapModule in my lazy loaded module as well. Then with setTimeout of 2 seconds the pop-up works. I guess in your tutorial the tour begins when someone clicks a button and hence the tourAnchor elements get enough time to be registered. Whereas in my case I wanted the tour to start as soon as the component is rendered. I tried this.tourService.start(); from various methods: constructor(), ngOnInit(), ngAfterViewInit(), but I eventually had to call it with setTimeout within ngOnInit(). I assumed that ngAfterViewInit() should at least work but it didn't. It would nice to know when exactly a user can fire this.tourService.start() instead of randomly calling it within a setTimeout(). Would you have any suggestions?

Also, I would like to thank you for this beautiful plugin. I'm happy to give the package a star.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/isaacplmann/ngx-tour/issues/76#issuecomment-359151058, or mute the thread https://github.com/notifications/unsubscribe-auth/AA0lQEn9BKRpTur22ZSS80aavo9jkHb4ks5tMY5kgaJpZM4RkRn- .

ranga-sriram commented 6 years ago

Thanks @isaacplmann, that helps

daiky00 commented 6 years ago

@ranga-sriram how did you solved the issues?

kmiasko commented 6 years ago

I'm having the same problem.

Where did the anchorRegistered$ go? Is isn't available in tourService anymore. There is anchorSubscribe$ but i don't know if thats the same.

this.tourService.events$
  .pipe(
    takeUntil(this.unsubscribe)
  )
  .subscribe(x => console.log(x));

this.tourService.anchorRegister$
  .pipe(
    takeUntil(this.unsubscribe)
  )
  .subscribe(anchor => {
    console.log('anchor subscribed', anchor);
    this.tourService.start();
  });
{name: "anchorRegister", value: "app-home"}
-> anchor subscribed app-home
{name: "start", value: undefined}

EDIT: ok i've managed to make it work, the solution was to remove the route property in tourService.initialize anchor configuration (it was fired directly in component with anchor).