0
votes

I have a signup process that consists of a few steps and would like to store the state within a service that can be accessed by each of the controllers for each of the steps.

I was able to get this working, but in a way that doesn't seem to jive with Ember's way of doing things. Instead of setting the controller's needs: value I had to add an initializer, which contains the following:

export default {
  name: 'signup-state',
  initialize: function(container, app) {

    app.inject('controller:signup/index',   'signup-state', 'service:signup-state');
    app.inject('controller:signup/method',  'signup-state', 'service:signup-state');

    app.inject('route:signup/method', 'signup-state', 'service:signup-state');
  }
};

The above was based on a comment by wycats on the discuss board [1].

Doing this just seems wrong. I would think that the needs controller would take care of this. So if this is just plain wrong stop me here since doing this a better way may fix the problem.

The above works, except for when it comes time to test the controller. When I call a method on the controller, that calls a method on the service, I get an error.

Here is the controller code

export default Ember.Controller.extend({

  /**
   * Reference to the signup-state service => initializers/signup-state.js
   */
  setState: function(key, val) {
    var state = this.get('signup-state');
    state.set(key, val);   <== state is undefined in tests
  },

  actions: {
    signupAsAdmin: function() {
      this.setState('userType', 'admin');
      this.transitionToRoute('signup.method');
    }
  }

});

And here is the controller TEST code

import { test, moduleFor } from 'ember-qunit';

moduleFor('controller:signup/index', 'SignupController', {
  needs: ['service:signup-state']
});

test('signing up as an admin set the userType state to admin', function() {
  var controller = this.subject();

  // blows up here => Cannot read property 'set' of undefined
  controller.send('signupAsAdmin');
});

Calling the signupAsAdmin function within the controller, results in making a set call on the service object, which results in an “undefined” error.

The initializer code is run as noted by adding console.log statements, but doesn't seem to result in making the service available to the controller during the tests.

Any help is appreciated.

Note: I am using ember-cli, so I don't have a global App variable available.

Update Manually registering (something I thought that ember-cli was doing) does work.

export default {
  name: 'signup-state',
  initialize: function(container, app) {

    app.register('service:signup-state', 'signup-state');

    // Remove Injects
    // app.inject('controller:signup/index',   'signup-state', 'service:signup-state');
    // app.inject('controller:signup/method',  'signup-state', 'service:signup-state');
  }
};

The above results in a null value returned when calling the get('signup-state') in the controller.

  1. http://discuss.emberjs.com/t/services-a-rumination-on-introducing-a-new-role-into-the-ember-programming-model/4947/10?u=olsen_chris
1
Do you register the service earlier on, so it can function as a factory for your dependency injection?Eric D. Johnson
I am using ember-cli so I was under the impression that registration was done for me. Am I wrong in assuming that?chris
Are you have a part out on the bleed-edge with all the toys then? :) I'm not sure, what magic it does, but it might be worth a go trying it manually. If you find a doc that tells how to spin that part up for you be sure to post it for us.Eric D. Johnson
Probably not the best way to start learning Ember, but the decision was made :)chris

1 Answers

0
votes

I'm new to the idea of using the dependency injection for a service so I might be missing something, but looking at this example test in the ember code base made me wonder, are you just missing a app.register('service:signup-state',App.ModelForSignupState) to give it bones?