diff --git a/lib/block.dart b/lib/block.dart
index b84b64969..b84d8b401 100644
--- a/lib/block.dart
+++ b/lib/block.dart
@@ -314,6 +314,7 @@ class ComponentFactory {
createAttributeMapping(Scope parentScope, Scope shadowScope, Parser parser) {
directive.$map.forEach((attrName, mapping) {
var attrValue = element.attributes[attrName];
+ if (attrValue == null) attrValue = '';
if (mapping == '@') {
shadowScope[attrName] = attrValue;
} else if (mapping == '=') {
diff --git a/test/compiler_spec.dart b/test/compiler_spec.dart
index 586b5904c..9f470b8dc 100644
--- a/test/compiler_spec.dart
+++ b/test/compiler_spec.dart
@@ -392,6 +392,7 @@ main() {
beforeEach(module((AngularModule module) {
module.directive(SimpleComponent);
module.directive(IoComponent);
+ module.directive(ParentExpressionComponent);
module.directive(PublishMeComponent);
}));
@@ -408,6 +409,35 @@ main() {
}));
}));
+ it('should create a component that can access parent scope', inject(() {
+ $rootScope.fromParent = "should not be used";
+ $rootScope.val = "poof";
+ var element = $('');
+
+ $compile(element)(injector, element);
+
+ ParentExpressionComponent.lastTemplateLoader.template.then(expectAsync1((_) {
+ expect(renderedText(element)).toEqual('inside poof');
+ }));
+ }));
+
+ it('should behave nicely if a mapped attribute is missing', inject(() {
+ var element = $('');
+ $compile(element)(injector, element);
+ ParentExpressionComponent.lastTemplateLoader.template.then(expectAsync1((_) {
+ expect(renderedText(element)).toEqual('inside ');
+ }));
+ }));
+
+ it('should behave nicely if a mapped attribute evals to null', inject(() {
+ $rootScope.val = null;
+ var element = $('');
+ $compile(element)(injector, element);
+ ParentExpressionComponent.lastTemplateLoader.template.then(expectAsync1((_) {
+ expect(renderedText(element)).toEqual('inside ');
+ }));
+ }));
+
it('should create a component with IO', inject(() {
var element = $(r'
');
$compile(element)(injector, element);
@@ -480,6 +510,15 @@ class IoComponent {
}
}
+class ParentExpressionComponent {
+ static String $template = 'inside {{fromParent()}}
';
+ static Map $map = {"fromParent": "&"};
+ static TemplateLoader lastTemplateLoader;
+ ParentExpressionComponent(Scope shadowScope, TemplateLoader templateLoader) {
+ lastTemplateLoader = templateLoader;
+ }
+}
+
class PublishMeComponent {
static String $template = r'{{ctrlName.value}}';
static String $publishAs = 'ctrlName';