benmarch / angular-ui-tour

Product tour using Angular UI Bootstrap Tooltips
163 stars 49 forks source link

Problems with detached tour, asynchronous steps and waitFor #114

Closed westor21 closed 7 years ago

westor21 commented 7 years ago

I am using the exact versions of the following libraries:

I have installed this library via: Bower

I'm using a detached tour:

uiTourService.createDetachedTour('MyTour', {backdrop: true, appendToBody: true, useUiRouter: false});

I have to handle some asynchronous steps while walking the tour. On the first page some synchronous steps are working fine. But then a have to request the backend and to move to the next page (using ui-router with $state.$go). Here is, how I'm doing this:

vm.waitForTourStep = function (fktBefore, stepId) {
   var tour = TourService.getTour();
   fktBefore();
   return tour.waitFor(stepId);
}

fktBefore is the async function, performing the request and the state change.

Here is the corresponding html

<button
        tour-step="s30"
        tour-step-belongs-to="MyTour"
        tour-step-title="Title s30"
        tour-step-content='Content s30'
        tour-step-order="30"
        tour-step-placement="bottom"
        tour-step-on-next="AppCtrl.waitForTourStep(Ctrl.asyncFkt,'s40')"
        ng-click="Ctrl.asyncFkt()"><span
        class="glyphicon glyphicon-arrow-right-filled"></span> Goto Next
</button>

The first problem was, the target element on page 2 was not rendered, when the next step tryed to pop up. And I can see in the console an error: Possibly unhandled rejection: undefined undefined. I tryed to find the first problem and modified your code, and now I can see the target element, if I use a timeout at 2 places in your code, starting from line 1021:

return handleEvent(step.config('onShow')).then(function () {
  if (step.config('backdrop')) {
    $timeout(function() {
      uiTourBackdrop.createForElement(step.element, step.config('preventScrolling'), step.config('fixed'), step.config('onBackdropClick'), step.config('backdropBorderRadius'));
    });
  }
}).then(function () {
    $timeout(function() {
       step.element.addClass('ui-tour-active-step');
    });
    return dispatchEvent(step, 'uiTourShow');
}).then(function () {

  return digest();
}).then(function () {

  return handleEvent(step.config('onShown'));
}).then(function () {

  self.emit('stepShown', step);
  step.isNext = isNext;
  step.isPrev = isPrev;
});

But it's still far from be expected behaviour: The error in the console is still there. The list of toursteps is empty on the second page, the previous button is not displayed (ok, I assume, I would have to implement a tour-on-previous function), and when I click on next, the waitFor function in the AppCtrl - here defined with

tour-step-on-next="AppCtrl.waitForTourStep(Ctrl2.asyncFkt,'s50')"

is not called. The tour stops silently, and the backdrop is not removed.

Do you have any help?

westor21 commented 7 years ago

Ok, for the problem of silently stopping the tour I found the bug by myself. AppCtrl was not on the current scope at page 2.

benmarch commented 7 years ago

Do you get the error when clicking the "Next" button on the tour step or when clicking your "Goto Next" button or both?

westor21 commented 7 years ago

I only get this, when I click the tour button.

benmarch commented 7 years ago

Ok thanks, I'll take a look. I don't have any test cases for waitFor() with a detached tour so I'll have to add that.

westor21 commented 7 years ago

One more problem: When starting the tour, the url hash is removed. Should I open onother issue for this, or is there a quick fix? As a workaround I think I could use lifecycle events to save and reset the correct hash.

benmarch commented 7 years ago

Hey @westor21, that came up in #100. I have officially deprecated the functionality that causes that issue, and it will be completely removed in 1.0.0, which I'm hoping to release in the next few months. I'm sorry that development has been slow lately, I've been traveling for work every few weeks and I haven't had much time to work on this. In the meantime, @FlowerFountain mentioned that turning html5 mode on fixed the issue (not sure if that works for you). Sorry for the inconvenience, I will fix it as soon as possible.

westor21 commented 7 years ago

OK, I see what you mean :-) Same problems often for me.... BTW: great Library. HTM5 mode is currently not an option, I tryed to remove the $location dependency in your code, but it is still removing the hash - I can't see the reason for quick. Can you tell me the lines I have to check for?

benmarch commented 7 years ago

Hey @westor21, I think I found the cause of your original issue. As of Angular 1.6, errors and rejections that bubble up without being caught are rethrown as an actual error. Here is a workaround: http://stackoverflow.com/a/41993170/1902587

I was not able to reproduce the hash removal issue locally. Were you able to find a workaround for that?

westor21 commented 7 years ago

Hallo @benmarch - ok, thank you for your investigation, so I can ignore this error or use the workaround. Regarding the hash removal problem, it was an issue which had nothing to do with angular-ui-tour.

benmarch commented 7 years ago

Hey @westor21, are you still seeing any issues related to the ones described here?

westor21 commented 7 years ago

Hallo @benmarch - currently we are using the tour without any asynchronous behaviour or routing, because we had some problemes with it.

benmarch commented 7 years ago

Thanks, @westor21. I am going to close this issue for now. Feel free to reopen if you come across it again.