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

fix(ngMessagesInclude): do not compile template if scope is destroyed #14640

Closed
wants to merge 2 commits into from
Closed

fix(ngMessagesInclude): do not compile template if scope is destroyed #14640

wants to merge 2 commits into from

Conversation

jpekkala
Copy link
Contributor

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Bug fix

What is the current behavior? (You can also link to an open issue here)
#12695

What is the new behavior (if this is a feature change)?

Does this PR introduce a breaking change?

Please check if the PR fulfills these requirements

Other information:

Messages imported with ngMessagesInclude are loaded asynchronously and they can arrive after the ngMessages element has already been removed from DOM. Previously such messages were still compiled and that caused a $compile:ctreq error. Now they are silently ignored if ngMessagesInclude's scope has already been destroyed.

Closes #12695

Messages imported with ngMessagesInclude are loaded asynchronously and they can arrive after the ngMessages element has already been removed from DOM. Previously such messages were still compiled and that caused a $compile:ctreq error. Now they are silently ignored if ngMessagesInclude's scope has already been destroyed.

Closes #12695
$rootScope.$digest();
$compile.calls.reset();
$httpBackend.flush();
expect($compile).not.toHaveBeenCalled();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of spying on compile, I'd rather see an expectation for not throwing, or a check that validates the DOM structure is as we expect it. The call to compile is a bit to implementation specific for me

it('should not compile template if scope is destroyed', function() {
module(function($provide) {
$provide.decorator('$compile', ['$delegate', function($delegate) {
var result = jasmine.createSpy('$compile').and.callFake($delegate);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return spyOn($delegate).and.callThrough(); is more straight-forward.

@jpekkala
Copy link
Contributor Author

Thanks for the reviews @Narretz and @gkalpak. An expectation for not throwing was my first idea too but after seeing the analogous test in ngInclude, I decided to do it the same way as they had.

This is how I would write the test with the expectation for not throwing:

it('should not throw if scope has been destroyed when template request is ready',
  inject(function($rootScope, $httpBackend, $compile) {
    $httpBackend.expectGET('messages.html').respond('<div ng-message="a">A</div>');
    $rootScope.show = true;
    var html =
        '<div ng-if="show">' +
          '<div ng-messages="items">' +
            '<div ng-messages-include="messages.html"></div>' +
          '</div>' +
        '</div>';

    element = $compile(html)($rootScope);
    $rootScope.$digest();
    $rootScope.show = false;
    $rootScope.$digest();
    expect(function() {
      $httpBackend.flush();
    }).not.toThrow();
}));

Should I update the pull request?

@Narretz
Copy link
Contributor

Narretz commented May 22, 2016

In that case, can you just add the not.toThroe expectation?

Use an expectation for not throwing instead of spying on $compile in order to keep the test less implementation specific.
petebacondarwin pushed a commit that referenced this pull request May 23, 2016
Messages imported with `ngMessagesInclude` are loaded asynchronously and
they can arrive after the ngMessages element has already been removed from DOM.

Previously we tried to compile these messages and that caused a `$compile:ctreq`
error. Now they are silently ignored if `ngMessagesInclude`'s scope has already
been destroyed.

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

Successfully merging this pull request may close these issues.

ngMessagesInclude processed after parent ngMessages is removed from DOM
4 participants