Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Cannot set property 'pur' of undefined #16164

Closed
1 of 3 tasks
Thrilleratplay opened this issue Aug 10, 2017 · 10 comments
Closed
1 of 3 tasks

Cannot set property 'pur' of undefined #16164

Thrilleratplay opened this issue Aug 10, 2017 · 10 comments

Comments

@Thrilleratplay
Copy link

I'm submitting a ...

  • bug report
  • feature request
  • other (Please do not submit support requests here (see above))

Current behavior:
After upgrading to v1.6.5, a panel whose visibility delayed using $timeout is throwing an error angular.js:14642 TypeError: Cannot set property 'pur' of undefined

Expected / new behavior:
Timeout cancelation should fail gracefully

Minimal reproduction of the problem with instructions:
Unfortunately I have not been able to create a Plunker that recreates this issue. In the environment I am working in, I am able to regularly reproduce this error by moving the mouse in and out of the element that triggers the showPanel/hidePanel functions three or four times.

Below I have attached a stacktrace and relative code. Please let me know if this is insufficient and I will continue to try to recreate the issue in Plunker.

Angular version: 1.6.5 but not version 1.6.4

Browser: Chrome 60 (only browser tested)

Anything else:

I am assuming that it is related to this commit: fix($timeout/$interval): do not trigger a digest on cancel and the simplest fix would be to add a check here:

function markQStateExceptionHandled(state) {
  if (state) {
    state.pur = true;
  }
}

** Debugging information**

Stacktrace:

angular.js:14642 TypeError: Cannot set property 'pur' of undefined
    at markQStateExceptionHandled (angular.js:17320)
    at markQExceptionHandled (angular.js:17323)
    at Function.timeout.cancel (angular.js:20422)
    at e.i.hidePanel (scope.component.js:188)
    at fn (eval at compile (angular.js:15500), <anonymous>:4:186)
    at callback (angular.js:27285)
    at Scope.$eval (angular.js:18372)
    at Scope.$apply (angular.js:18472)
    at HTMLDivElement.<anonymous> (angular.js:27290)
    at specialMouseHandlerWrapper (angular.js:3782)
    at HTMLDivElement.eventHandler (angular.js:3759)
(anonymous) @ angular.js:14642
(anonymous) @ angular.js:11102
$apply @ angular.js:18477
(anonymous) @ angular.js:27290
specialMouseHandlerWrapper @ angular.js:3782
eventHandler @ angular.js:3759

Relative element with mouse event triggers

<div class="flex flex-auto relative"
     ng-mouseenter="scopeCtrl.showPanel()"
     ng-mouseleave="scopeCtrl.hidePanel()"
     ng-class="(scopeCtrl.collapsed ? 'closed' : 'open'">
  <!-- Additional content here-->
</div>

Relative JavaScript functions

var vm = this;
var panelTimer;

/**
 * Delayed show Scope panel
 */
vm.showPanel = function() {
  $timeout.cancel(panelTimer);
  panelTimer = $timeout(function() {
    vm.collapsed = false;
  }, 300);
};

/**
 * Delayed delayed Scope panel
 */
vm.hidePanel = function() {
  $timeout.cancel(panelTimer);
  panelTimer = $timeout(function() {
    vm.collapsed = true;
  }, 300);
};
@gkalpak
Copy link
Member

gkalpak commented Aug 10, 2017

This is very strange. All promises have a $$state property from the get go. I can't imagine how it is would be possible to end up at that point of the code with $$state being undefined 😕

A repro woud definitely help.

(Other than the missing repro, awesome bug report  ❤️ )

@Thrilleratplay
Copy link
Author

My apologies, this is an issue of my own creation and explains why I couldn't reproduce the issue on Plunker. I was using Bluebird.js with angular-bluebird-promises to override the built in Angular promise service for the cancelable promise feature. I guess these have both diverged enough from Kris Kowal's Q.

@gkalpak
Copy link
Member

gkalpak commented Aug 11, 2017

Hm....so I guess we have made it impossible (or possibly just harder than necessary) for people to swap $q with a different implementation 😕
If it is easy to fix and someone wants to take a look at what it would take to make it more straightforward, please go ahead.

@rickyk586
Copy link

rickyk586 commented Oct 11, 2017

Instead of using $mdToast.showSimple('Toast Message'), use:

$mdToast.show({
	template: '<md-toast><div class="md-toast-content">Toast Message</div></md-toast>',
	hideDelay: false
});
$timeout(() => $mdToast.hide(), 2900);

vbraun added a commit to vbraun/angular.js that referenced this issue Feb 26, 2018
For testing, it can be useful to run with other promise
implementations like Bluebird.js + angular-bluebird-promises. This
broke in angularjs 1.6 with a "TypeError: Cannot set property 'pur' of
undefined".

Closes angular#16164
@petebacondarwin
Copy link
Contributor

I'm going to land this with comments explaining why those if statements are there.

@petebacondarwin petebacondarwin self-assigned this Feb 26, 2018
@petebacondarwin petebacondarwin modified the milestones: Backlog, 1.6.x, 1.6.10 Feb 26, 2018
@wiltzius
Copy link

May I propose re-opening this issue? The PR referenced above #16471 landing would be very helpful -- we're currently stuck on 1.6.4 because we're relying on bluebird to install our own generic promise rejection handler. Much appreciated, thank you.

@gkalpak
Copy link
Member

gkalpak commented May 27, 2018

Hm...I think we were supposed to land #16471 (but didn't) 😕
Let's move the discussion there.

@wiltzius, do you by any chance know (or have a way to find out) the answer to https://github.com/angular/angular.js/pull/16471/files#r172260779?
(Or share a minimal reproduction, so I can investigate myself.)

@wiltzius
Copy link

Yes, here's a minimal repo:

https://github.com/wiltzius/angularjs-webpack

I just cloned a basic starter repo (https://github.com/preboot/angularjs-webpack) and then made the following changes to it:

wiltzius/angularjs-webpack@4b8342f

Hopefully that commit ^ should tell you all you need to know.

Obviously its contrived, but I basically copied the $interval code from ng-infinite-scroll (which is a project we're using that's causing this problem). See that code here:

https://github.com/sroze/ngInfiniteScroll/blob/master/src/infinite-scroll.js#L257

Appreciate you taking a look at this!

@wiltzius
Copy link

btw this is tagged 1.6.10 but 1.7.0 (all versions >= 1.6.5) exhibit the same behavior.

@gkalpak
Copy link
Member

gkalpak commented May 28, 2018

Thx! So, afaict (based on your repro) is that the answer to https://github.com/angular/angular.js/pull/16471/files#r172260779 is that isStateExceptionHandled() is indeed not called when not using the built-in $q.

@wiltzius, would you like to take over #16471, remove the unnecessary change to isStateExceptionHandled() and add a comment in markQStateExceptionHandled mentioning why it is needed?

gkalpak pushed a commit that referenced this issue Nov 15, 2018

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
For testing, it can be useful to overwrite `$q` with other promise
implementions, such as Bluebird + angular-bluebird-promises. This broke
in v1.6.x with "TypeError: Cannot set property 'pur' of undefined".

Closes #16164

Closes #16471
gkalpak pushed a commit that referenced this issue Nov 15, 2018

Unverified

This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
For testing, it can be useful to overwrite `$q` with other promise
implementions, such as Bluebird + angular-bluebird-promises. This broke
in v1.6.x with "TypeError: Cannot set property 'pur' of undefined".

Closes #16164

Closes #16471
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants