mdColors: Dynamic expression breaks when theme is specified #8720
Description
Actual behavior:
- What is the issue?
When a theme is provided via the mdTheme directive on a parent of an element which utilises the mdColors directive, and mdColors is using a dynamic expression, the colour fails to update.
- What is the expected behavior?
mdColors can be used with a dynamic expression regardless of whether a theme has been explicitly specified.
CodePen or Steps to reproduce the issue: *
- CodePen Demo which shows your issue: http://codepen.io/WFGTurtle/pen/VjezyK
- Details:
The pen shows two panels, which are identical in functionality, save for the fact that the panel on the right explicitly specifies 'md-theme="default"'. As can be seen, the panel on the left changes colour to the selected palette. The panel on the right does not.
Angular Versions: *
- Angular Version: 1.5.6
- Angular Material Version: 1.1.0-rc.5
Additional Information:
- Browser Type: Firefox & Chrome
- Browser Version: Firefox 46.0.1, Chrome 51.0.2704.84
- OS: Windows 10 x64
- Stack Traces:
00:39:47.004 Error: mdColors: couldn't find '[object object]' in the palettes.
Stack trace:
extractPalette@https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc.5/angular-material.js:7449:17
extractColorOptions@https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc.5/angular-material.js:7427:18
interpolateColors/<@https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc.5/angular-material.js:7395:21
q@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:8:1
interpolateColors@https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc.5/angular-material.js:7394:7
applyThemeColors@https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc.5/angular-material.js:7332:21
bb/<@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:16:150
uf/this.$get</m.prototype.$digest@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:142:443
uf/this.$get</m.prototype.$apply@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:145:399
listener@https://ajax.googleapis.com/ajax/libs/angular_material/1.1.0-rc.5/angular-material.js:18056:7
Rf@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:37:31
Qf/d@https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js:36:486
So, I've had a look into the issue, and I've found what I think is the source of the problem - the culprit is line 7558 of angular-material.js (1.1.0-rc.5), colors[prop] = (theme || mdThemeController.$mdTheme) + '-' + color;
.
It looks like what's happening is that when the expression for mdColors is dynamic, parseColors is added as a watchExpression (7583), which would be fine, but watchExpressions are called with scope
as a parameter, whereas parseColors is expecting an optional 'theme' as a parameter. When md-theme is present, mdThemeController is not null on line 7554 meaning line 7558 gets executed, which prepends the name of the theme to the color expression. The 'theme' parameter takes precedence over mdThemeController.$mdTheme
, but because 'theme' is actually a scope
object, we end up with an expression like '[object object]-accent' instead of 'default-accent', leading to the error seen in the stack trace.