Gabriel Rodrigues
Gabriel Rodrigues

Reputation: 143

How to use bindings in angular 1.5 components

Trying to write a simple login page I've encounter some difficulty in understanding why the .components bindings doesn't work.

Example

template: login.html

    <form>
  <fieldset>
        <label>Email</label>
        <input id="email" type="email" ng-model="login.user.email">

        <label>Senha</label>
        <input type="password" ng-model="login.user.pass">

        <button ng-click="login.test({text: login.user})">
          Entrar
        </button>
  </fieldset>
</form>

component: login.js

angular
  .module('app')
  .component('login', {
    bindings: {
      user: '<',
      test: '&'
    },
    templateUrl: 'app/login/login.html',
    controller: function ($log) {
      var vm = this;
      vm.user = {
        mail: '[email protected]',
        pass: ''
      };
      vm.test = consoleTest;

      function consoleTest(text) {
        $log.info('test! text:'+text);
      }
    }
  });

route: router.js

angular
  .module('app')
  .config(routesConfig);

/** @ngInject */
function routesConfig($stateProvider, $urlRouterProvider, $locationProvider) {
  $locationProvider.html5Mode(true).hashPrefix('!');
  $urlRouterProvider.otherwise('/');

  $stateProvider
    .state('login', {
      url: '/login',
      component: 'login'
    });
}

The route does not load and shows up the errors:

stateService.ts:530 TypeError: Cannot read property '2' of null
    at http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7096:54
    at Array.map (native)
    at scopeBindings (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7096:7)
    at getBindings (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7101:17)
    at Array.map (native)
    at getComponentInputs (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7109:21)
    at config.templateProvider (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7074:34)
    at invokeResolveFn (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:2786:37)
    at processQueue (http://localhost:3000/bower_components/angular/angular.js:16843:37)
    at http://localhost:3000/bower_components/angular/angular.js:16887:27
$defaultErrorHandler @ stateService.ts:530
(anonymous) @ stateService.ts:352
processQueue @ angular.js:16843
(anonymous) @ angular.js:16887
$digest @ angular.js:17982
$apply @ angular.js:18280
bootstrapApply @ angular.js:1912
invoke @ angular.js:5003
doBootstrap @ angular.js:1910
bootstrap @ angular.js:1930
angularInit @ angular.js:1815
(anonymous) @ angular.js:33340
trigger @ angular.js:3435
stateService.ts:531 TypeError: Cannot read property '2' of null
    at http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7096:54
    at Array.map (native)
    at scopeBindings (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7096:7)
    at getBindings (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7101:17)
    at Array.map (native)
    at getComponentInputs (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7109:21)
    at config.templateProvider (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:7074:34)
    at invokeResolveFn (http://localhost:3000/bower_components/angular-ui-router/release/angular-ui-router.js:2786:37)
    at processQueue (http://localhost:3000/bower_components/angular/angular.js:16843:37)
    at http://localhost:3000/bower_components/angular/angular.js:16887:27

Just removing the test: '&' property in bindings and the route loads with no errors in console, but the ng-model does not link up to the controller so it doesn't update the input field with the hard-coded value.

How can I make those bindings work?

Upvotes: 0

Views: 163

Answers (1)

Gary
Gary

Reputation: 96

You will need to use angularjs lifecycle hooks to initialise the data you want:

vm.$onInit = function() {
  vm.user = {
    mail: '[email protected]',
    pass: ''
  };
}

You also won't need to bind test as you will have access to the controller in the component, as you are using a routed component not a stateless one.

If you were using a stateless component you would need to bind test and use it as a callback function to pass the data back after an event.

Upvotes: 1

Related Questions