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

Race conditions with existing animation runner (replace, templateUrl) #13215

Closed
Foxandxss opened this issue Oct 31, 2015 · 10 comments
Closed

Race conditions with existing animation runner (replace, templateUrl) #13215

Foxandxss opened this issue Oct 31, 2015 · 10 comments

Comments

@Foxandxss
Copy link
Member

Hello,

I have an issue that I am not really sure if it is something that ngAnimate should fix or it has to be managed in the end applications.

I am using $animate.enter to bring some DOM to the screen and then $animate.leave to delete them (a popup message). Works good. The problem comes when you try to make them leave while they are running. The new ngAnimate (1.4.0+) has a new mechanism to cancel running animations, but it fails under some corner cases.

Check this plunker (Angular 1.4.7)
Check this plunker (Angular 1.4.7, no ngAnimate)
Check this plunker (Angular 1.3.20, ngAnimate)

The close behavior in there is crappy, but reproduces my issue. My first impression is that even when .leave is called with a proper element, it gets deleted in the mean time so when it reaches ngAnimate, there is nothing to work with and it throws an exception.

This is a poor reproduction of Foxandxss/angular-toastr#136

There is a plunker with the real issue. Also going back to 1.3.20 fixes it.

So, should I somehow prevent this? Or ngAnimate should be able to do this correctly? I want to think about the latter since it used to work.

Thank you.

@Narretz
Copy link
Contributor

Narretz commented Nov 13, 2015

If it worked before, it's most likely a regression. Thanks for reporting.

@Narretz
Copy link
Contributor

Narretz commented Nov 19, 2015

This is due to a combination of replace and templateUrl on the directive. Replace is also deprecated, you should consider not using it. You could also use the template Property instead of templateUrl.

However, I've noticed another bug: after the leave animation finishes, the element is still in the DOM until some timeout finishes. This happens only if an enter animation is still running.

@Foxandxss
Copy link
Member Author

I have noticed that latter bug indeed.

I am planning a 2.0.0 version of my lib without replace, not sure if that would fix it. About using template instead of templateUrl, not sure if I can make it without making it more problematic for end users. Keep in mind that it is a library and not a end application. As today people are struggling about caching templates before use them (which is problematic if you don't), if I need to make them do anything complicated to change to template.

So I am not asking Angular to workaround this for me. If this is something solved in userland, I will workaround myself, but I think it is still a regression.

@Narretz
Copy link
Contributor

Narretz commented Nov 19, 2015

I think we should definitely fix the different behavior of templateUrl vs. template property, but as replace has been deprecated since 1.3?, it just means you shouldn't bet on this being fixed.

@Foxandxss
Copy link
Member Author

You know what is the problem with replace? That once you have it, it is hard to move on without it. In the case of my library, it is pretty tied to that, and if you look to ui-bootstrap, we have lots in there that are not easy to remove.

I will rewrite my whole CSS to remove replace and for ui-bootstrap I will do what is needed for the 1.0.0 release that is close.

Thanks @Narretz

@Narretz Narretz modified the milestones: 1.4.9, 1.4.x Nov 30, 2015
@Narretz Narretz changed the title Race conditions with existing animation runner Race conditions with existing animation runner (replace, templateUrl) Dec 11, 2015
@matsko
Copy link
Contributor

matsko commented Jan 13, 2016

@Foxandxss sorry for this taking a few months to get resolved.

Your best bet is to use template and to include the contents of the toast directly into the directive definition. This avoids a couple of extra digest cycles and the http download of toast.html (which is what causes the race condition in the first place).

We ran into this issue with transclusion as well and there was no proper solution. If your code is still relying on replace:true then maybe what can happen is that ngAnimate inspects the element to see if the element will be replaced and then it skips animations for the to-be-replaced directive element. This way when the replaced value kicks in then there are no animations in the way. Is this something you still need?

@Foxandxss
Copy link
Member Author

Can I use template but still allow custom templates? I will think about that.

About replace, yes, I have to remove it. The CSS is inherited from the library I created the original rewrite and it is made for a concrete html structure that I cannot replicate without replace. So I need to rewrite the CSS which is another history.

@samypr100
Copy link

Any updates on this? I'm really sorry for the bump.

@wesleycho
Copy link
Contributor

This should probably be closed given that replace: true has been marked as deprecated for a while.

We encountered issues in UI Bootstrap as well I believe, but we're in the process of stripping out replace: true (finally!)

@gkalpak
Copy link
Member

gkalpak commented Jun 14, 2016

I agree that since replace: true has been deprecated, this corner-case isn't likely to be fixed.
FWIW, it (kind of) works if you defer adding the element to the list of toasts to be removed, until the enter animation has been completed: demo
(There is still an error in the console, but it seems to work 😞 )

@gkalpak gkalpak closed this as completed Jun 14, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants