1

I've got the following code, where I expect the content of the property variable to be displayed in the page. I read a couple of posts and tried to find out what I'm doing wrong, but couldn't find the error. Here is the code:

namespace testWeb.about {
    class AboutComponent implements ng.IComponentOptions {
        templateUrl = "scripts/components/about/about.html";
        controller = AboutController;
        bindings: any;

        constructor() {
            this.bindings = {
                awesomeThings : '<',
                property : '<'
            };
        }
    }

    interface IAboutController {
        awesomeThings: Array<string>;
        property: string;
    }

    export class AboutController implements IAboutController, ng.IComponentController {
        awesomeThings: Array<string>;
        property: string;

        constructor() {
            this.awesomeThings = [
                "one",
                "two",
                "three"
            ];
            this.property = "123";
        }
    }
    angular.module("test_web")
        .component("about", new AboutComponent())
        .config(($stateProvider) => {
            "ngInject";
            $stateProvider
                .state("about", {
                    url: "/about",
                    template: `<about></about>`
                });
        });
}

Whether <span ng-repeat="dd in $ctrl.awesomeThings">{{dd}}</span> nor <span class="as">{{$ctrl.property}}</span> gets displayed.

<span ng-repeat="dd in $ctrl.awesomeThings">{{dd}}</span>
<span class="as">{{$ctrl.property}}</span>
<p>123</p>

1 Answer 1

1

This behaviour is caused by disabled pre-assigned bindings in Angular 1.6.

In 1.5, this.property = "123" overwrites initial binding value, even if it was provided.

In 1.6, the binding is assigned after constructor call. If a value for the binding is not provided, property is assigned to undefined.

To prevent this and provide the desired behaviour bindings should be marked as optional:

this.bindings = {
    awesomeThings : '<?',
    property : '<?'
};

Alternatively, initial values can be assigned in $onInit hook, this allows to ignore falsy initial values from bindings for example:

constructor() {}

$onInit() {
    this.awesomeThings = this.awesomeThings || [
        "one",
        "two",
        "three"
    ];
    this.property = this.property || "123";
}
Sign up to request clarification or add additional context in comments.

2 Comments

Should I use $onInit when optional bindings not working? Trying to create some dynamic menu with ng-repeat in the initial component, but cannot get it work.
Yes, this is how it is supposed to work, all initialization code goes to $onInit (which is an an alternative to directive pre-link function), unless it is known that code should be in constructor. For legacy components that are not ready for 1.6 see also toddmotto.com/angular-1-6-is-here#re-enabling-auto-bindings . ng-repeat has weird timing, so if the problem persists even with $onInit, it may be specific to ng-repeat .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.