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

compiler: improve support for AngularJS 1.7.2+ #11319

Closed
Splaktar opened this issue Jun 7, 2018 · 5 comments · Fixed by #11320
Closed

compiler: improve support for AngularJS 1.7.2+ #11319

Splaktar opened this issue Jun 7, 2018 · 5 comments · Fixed by #11320
Assignees
Labels
for: internal contributor The team will address this issue and community PRs are not requested. has: Pull Request A PR has been created to address this issue P1: urgent Urgent issues that should be addressed in the next minor or patch release. resolution: fixed type: conflict
Milestone

Comments

@Splaktar
Copy link
Contributor

Splaktar commented Jun 7, 2018

Bug, enhancement request, or proposal:

Proposal

CodePen and steps to reproduce the issue:

Demo which demonstrates the issue:

https://travis-ci.org/angular/material/jobs/388688438 is just one of many CI unit test jobs which have failed for the AngularJS SNAPSHOT view since angular/angular.js#16580 was merged.

What is the expected behavior?

AngularJS Material unit tests in master pass against the AngularJS SNAPSHOT version.

What is the current behavior?

54 failing tests can be seen in all recent jobs like https://travis-ci.org/angular/material/jobs/388688438.

What is the use-case or motivation for changing an existing behavior?

We were fairly well prepared for the changes in angular/angular.js#15782 that went into AngularJS 1.7.0, but the follow on breaking changes in angular/angular.js#16580 that are part of the unreleased AngularJS 1.7.1 remove some private and undocumented APIs that AngularJS Material depended upon.

One example is the use of the third and fourth arguments in $controller which were added to fix an issue with ES6 that we resolved in 1.1.5. You can see some of the comments that explain this here:

MdCompilerService.prototype._createController = function(options, injectLocals, locals) {
// The third and fourth arguments to $controller are considered private and are undocumented:
// https://github.com/angular/angular.js/blob/master/src/ng/controller.js#L86
// Passing `true` as the third argument causes `$controller` to return a function that
// gets the controller instance instead returning of the instance directly. When the
// controller is defined as a function, `invokeCtrl.instance` is the *same instance* as
// `invokeCtrl()`. However, then the controller is an ES6 class, `invokeCtrl.instance` is a
// *different instance* from `invokeCtrl()`.
var invokeCtrl = this.$controller(options.controller, injectLocals, true, options.controllerAs);
if (getPreAssignBindingsEnabled() && options.bindToController) {
angular.extend(invokeCtrl.instance, locals);
}
// Instantiate and initialize the specified controller.
var ctrl = invokeCtrl();
if (!getPreAssignBindingsEnabled() && options.bindToController) {
angular.extend(ctrl, locals);
}
// Call the $onInit hook if it's present on the controller.
angular.isFunction(ctrl.$onInit) && ctrl.$onInit();
return ctrl;
};
.

Which versions of AngularJS, Material, OS, and browsers are affected?

  • AngularJS: 1.7.1
  • AngularJS Material: All
  • OS: All
  • Browsers: All

Is there anything else we should know? Stack Traces, Screenshots, etc.

We cover some of the details of $compileProvider.preAssignBindingsEnabled() in our updated docs for 1.1.9 here: https://material.angularjs.org/latest/api/service/$mdCompilerProvider#mdcompilerprovider-respectpreassignbindingsenabled-respected

@Splaktar Splaktar added for: internal contributor The team will address this issue and community PRs are not requested. type: conflict needs: investigation The cause of this issue is not well understood and needs to be investigated by the team or community P1: urgent Urgent issues that should be addressed in the next minor or patch release. hotlist: Angular 1.7 support labels Jun 7, 2018
@Splaktar Splaktar added this to the 1.1.10 milestone Jun 7, 2018
@Splaktar Splaktar self-assigned this Jun 7, 2018
@Splaktar
Copy link
Contributor Author

Splaktar commented Jun 7, 2018

@gkalpak provided this guidance:

So, this method needs to be refactored so that it doesn't pass the 3rd argument to $controller() if AngularJS is at v1.7.1 or higher 😁

MdCompilerService.prototype._createController = function(options, injectLocals, locals) {
// The third and fourth arguments to $controller are considered private and are undocumented:
// https://github.com/angular/angular.js/blob/master/src/ng/controller.js#L86
// Passing `true` as the third argument causes `$controller` to return a function that
// gets the controller instance instead returning of the instance directly. When the
// controller is defined as a function, `invokeCtrl.instance` is the *same instance* as
// `invokeCtrl()`. However, then the controller is an ES6 class, `invokeCtrl.instance` is a
// *different instance* from `invokeCtrl()`.
var invokeCtrl = this.$controller(options.controller, injectLocals, true, options.controllerAs);
if (getPreAssignBindingsEnabled() && options.bindToController) {
angular.extend(invokeCtrl.instance, locals);
}
// Instantiate and initialize the specified controller.
var ctrl = invokeCtrl();
if (!getPreAssignBindingsEnabled() && options.bindToController) {
angular.extend(ctrl, locals);
}
// Call the $onInit hook if it's present on the controller.
angular.isFunction(ctrl.$onInit) && ctrl.$onInit();
return ctrl;
};

This appears to just be one step of many towards fixing this. Making this change alone still results in 54 failing tests.

If I make some changes to respectPreAssignBindingsEnabled in compiler.js and compiler.spec.js, I can get the failures down to 48. Most of them are from InterimElements like Dialog, Toast, Panel, but I'm still seeing 6 mdCompiler errors that all look like this:

	TypeError: invokeCtrl is not a function
	    at MdCompilerService.MdCompilerProvider.MdCompilerService._createController (src/core/services/compiler/compiler.js:477:16)
	    at Object.linkFn [as link] (src/core/services/compiler/compiler.js:432:25)
	    at UserContext.<anonymous> (src/core/services/compiler/compiler.spec.js:131:14)
	    at Object.invoke (node_modules/angular/angular.js:5090:17)
	    at UserContext.WorkFn (node_modules/angular-mocks/angular-mocks.js:3261:20)
	Error: Declaration Location
	    at window.inject.angular.mock.inject (node_modules/angular-mocks/angular-mocks.js:3224:25)
	    at Suite.<anonymous> (src/core/services/compiler/compiler.spec.js:120:53)
	    at Suite.<anonymous> (src/core/services/compiler/compiler.spec.js:109:5)
	    at Suite.<anonymous> (src/core/services/compiler/compiler.spec.js:16:3)

@Splaktar Splaktar added has: Pull Request A PR has been created to address this issue and removed needs: investigation The cause of this issue is not well understood and needs to be investigated by the team or community labels Jun 7, 2018
@Splaktar
Copy link
Contributor Author

Splaktar commented Jun 7, 2018

PR #11320 is open and appears to fix all of the tests for AngularJS SNAPSHOT while not breaking any of the tests against AngularJS 1.5 and 1.6.

@Splaktar Splaktar changed the title compiler: stop using private and are undocumented $controller arguments compiler: refactor to support AngularJS 1.7.1 Jun 7, 2018
@gkalpak
Copy link
Member

gkalpak commented Jun 7, 2018

this method needs to be refactored so that it doesn't pass the 3rd argument to $controller() if AngularJS is at v1.7.1 or higher

To be clear, by "refactored" I meant making it so that it doesn't rely on the removed AngularJS feature (3rd argument) in addition to not passing the argument 😁

Splaktar added a commit that referenced this issue Jun 7, 2018
remove use of private and undocumented arguments to $controller
update how preAssignBindingsEnabled is handled for AngularJS 1.7+

Fixes #11319
Splaktar added a commit that referenced this issue Jun 8, 2018
remove use of private and undocumented arguments to $controller
update how preAssignBindingsEnabled is handled for AngularJS 1.7+
update documentation

Fixes #11319
Splaktar added a commit that referenced this issue Jun 8, 2018
remove use of private and undocumented arguments to $controller
update how preAssignBindingsEnabled is handled for AngularJS 1.7+
update documentation

Fixes #11319
@sgilroy
Copy link

sgilroy commented Jun 13, 2018

It looks like the removal of preAssignBindingsEnabled was reverted in AngularJS 1.7.2 https://github.com/angular/angular.js/blob/master/CHANGELOG.md#172-extreme-compatiplication-2018-06-12

Does this resolve the compatibility problem, at least for AngularJS 1.7.2? Are you still planning to move forward with attempting to eliminate use of preAssignBindingsEnabled?

@Splaktar
Copy link
Contributor Author

@sgilroy yes it was reverted in 1.7.2. Yes it solves the compatibility problem with 1.7.2 and AngularJS Material. We're re-evaluating our approach due to that change. We do still plan to eliminate respectPreAssignBindingsEnabled in AngularJS Material 1.2.0.

Splaktar added a commit that referenced this issue Jun 19, 2018
remove use of private and undocumented arguments to $controller
update how preAssignBindingsEnabled is handled for AngularJS 1.7+
update documentation

Fixes #11319
Splaktar added a commit that referenced this issue Jun 19, 2018
remove one of two uses of private/undocumented arguments to $controller
mark setting `respectPreAssignBindingsEnabled(false)` as deprecated
update documentation
add AngularJS 1.5.x back to TravisCI
update AngularJS devDependencies to `^1.7.2`

Closes #11319
Splaktar added a commit that referenced this issue Jun 20, 2018
remove one of two uses of private/undocumented arguments to $controller
mark setting `respectPreAssignBindingsEnabled(false)` as deprecated
update documentation
add AngularJS 1.5.x back to TravisCI
update AngularJS devDependencies to `^1.7.2`

Closes #11319
Splaktar added a commit that referenced this issue Jun 20, 2018
remove one of two uses of private/undocumented arguments to $controller
mark setting `respectPreAssignBindingsEnabled(false)` as deprecated
update documentation
add AngularJS 1.5.x back to TravisCI
update AngularJS devDependencies to `^1.7.2`

Closes #11319
jelbourn pushed a commit that referenced this issue Jun 22, 2018
remove one of two uses of private/undocumented arguments to $controller
mark setting `respectPreAssignBindingsEnabled(false)` as deprecated
update documentation
add AngularJS 1.5.x back to TravisCI
update AngularJS devDependencies to `^1.7.2`

Closes #11319
@Splaktar Splaktar changed the title compiler: refactor to support AngularJS 1.7.1 compiler: refactor to support AngularJS 1.7.2+ Jun 22, 2018
@Splaktar Splaktar changed the title compiler: refactor to support AngularJS 1.7.2+ compiler: improve support for AngularJS 1.7.2+ Jun 22, 2018
Splaktar added a commit that referenced this issue Jul 31, 2018
remove one of two uses of private/undocumented arguments to $controller
mark setting `respectPreAssignBindingsEnabled(false)` as deprecated
update documentation
add AngularJS 1.5.x back to TravisCI
update AngularJS devDependencies to `^1.7.2`

Closes #11319
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
for: internal contributor The team will address this issue and community PRs are not requested. has: Pull Request A PR has been created to address this issue P1: urgent Urgent issues that should be addressed in the next minor or patch release. resolution: fixed type: conflict
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants