pbastowski / angular2-now

Angular 2 @Component syntax for Angular 1 apps

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

I'm not sure if my controllers are being created properly.

vacarsu opened this issue · comments

I have a state setup as follows

@State({
  name: 'root.register',
  url: '/register',
  templateUrl: 'client/components/register/register.ng.html'
})
@Inject(['$rootScope', '$meteor', '$state'])

class register {
  constructor($rootScope, $meteor, $state) {
    this.$meteor = $meteor;
    this.$state = $state;
    console.log($rootScope.currentUser);
  }

  register(user) {
    this.$meteor.createUser({
      username: user.email,
      email: user.email,
      profile: {
        displayName: user.firstName + ' ' + user.middleInitial + ' ' + user.lastName,
        firstName: user.firstName,
        middleInitial: user.middleInitial,
        lastName: user.lastName,
        accountType: user.accountType
      },
      password: user.password
    })
    .then(() => {
      this.$state.go('root.home');
    },
    err => {
      console.log(err);
    })
  }
}

I have tried accessing the register function in the template via register.register(), and I have also tried setting the scope name via angular2now.options({ controllerAs: 'vm' }); in app.es6.js. Both ways seem to not work. However, when I go to the state at /register the $rootScope.currentUser does get logged as undefined which is expected.

The reason why register.anything is not working is because you don't have a @component defined for this route. Only components create their own private scope that you can access through the camelCased component selector name, in your case register.

The example code is what I would call the "old" way of defining routes with controllers and templates :)

Consider doing it this way instead:

@State({
  name: 'root.register',
  url: '/register',
})

@Component('register')  // shortcut for selector: 'register'
@View('client/components/register/register.ng.html')  // shortcut for templateUrl: '....'
@Inject(['$rootScope', '$meteor', '$state'])

class register {
  constructor($rootScope, $meteor, $state) {
    this.$meteor = $meteor;
    this.$state = $state;
    console.log($rootScope.currentUser);
  }

  register(user) {
    this.$meteor.createUser({
      username: user.email,
      email: user.email,
      profile: {
        displayName: user.firstName + ' ' + user.middleInitial + ' ' + user.lastName,
        firstName: user.firstName,
        middleInitial: user.middleInitial,
        lastName: user.lastName,
        accountType: user.accountType
      },
      password: user.password
    })
    .then(() => {
      this.$state.go('root.home');
    },
    err => {
      console.log(err);
    })
  }
}

With the above change, you will have access in your template to register.register(user).

Alternatively, you could inject $scope into the constructor and put all your functions on $scope. But, with angular2now we are trying to move away from controllers and scope on to components.

...
@Inject([ '$rootScope', '$meteor', '$state', '$scope' ])

class register {
  constructor($rootScope, $meteor, $state, $scope) {
    $scope.register = function () { .... }
...

The above is not what I designed angular2now for.

Okay that makes sense, so I must create a component for it, but I don't necessarily have to use the selector for it?

Each component always has a selector.

Have a look at this example to see how it all fits together. It is in ES5, but you will notice familiar things:

http://plnkr.co/edit/uxV781?p=preview

Thanks for that example, I get it now. Got it all working.