javascriptangularjsangularjs-scopeangularjs-model

accessing values from an object model using 'controller as' $scope angularJS


I'm attempting to grab the user.firstName and user.lastName, add a watch collection to those models, and spit back out a userName.

I can't seem to communicate between the two, I think I'm using scope and self incorrect. I'm pretty new and misunderstanding the two concepts.

And because I'm getting an error, what is the proper way to grab lastName and firstName from the $user object, and spit back out something to the view?

I'm using the 'controller as' syntax. Ty for any guidance.

HTML

<input ng-model="ctrl.user.firstName" required>
<input ng-model="ctrl.user.lastName" required>
<input type="text" value="{{userName}}" name="user_name" ng-model="ctrl.user.userName">

JS

var self = this
$scope.$watchCollection('[user.firstName, user.lastName]', function () {
    if (self.user.firstName != '' && self.user.lastName != '') {
        $scope.userName = self.user.firstName + '_' + self.user.lastName + '_' + Math.floor((Math.random() * 100000) + 1);
        $scope.user.userName.$setViewValue($scope.userName);
    }
});

Solution

  • $watchCollection is evaluated against scope, so you need:

    var self = this
    self.user = {};
    $scope.$watchCollection('[ctrl.user.firstName, ctrl.user.lastName]', function () {
        if (self.user.firstName != '' && self.user.lastName != '') {
            $scope.userName = self.user.firstName + '_' + self.user.lastName + '_' + Math.floor((Math.random() * 100000) + 1);
            self.user.userName.$setViewValue($scope.userName);
        }
    });
    

    Also, I don't think you need to worry about using $setViewValue, just change to:

    $scope.$watchCollection('[ctrl.user.firstName, ctrl.user.lastName]', function () {
        if (self.user.firstName != '' && self.user.lastName != '') {
            self.user.userName = self.user.firstName + '_' + self.user.lastName + '_' + Math.floor((Math.random() * 100000) + 1);
        }
    });
    

    and your html to:

    <input type="text" name="user_name" ng-model="ctrl.user.userName">
    

    the "name" attribute is only used if you are embedding the input in a form. If that is the case, you can access for validation, etc, with

    $scope.formName.user_name