ryanto / ember-flash-message

Flash message for Ember.JS templates.
49 stars 23 forks source link

Any way to use from controller? #2

Closed cjroebuck closed 10 years ago

cjroebuck commented 10 years ago

Hi there, thanks for creating this. Is there an easy way to put up a flash message from a controller? Usual use case is after a model is updated or saved inside a controller action, and I want to put up a flash message with success/error status, currently using it from router only doesn't allow me to express these situations, unless im missing something..

Guess we would have to inject it into each controller using application initializer?

emilford commented 10 years ago

+1 for being able to use this from a controller

I am just starting out with Ember.js and am sure there is a better way to do this, but I am handling multiple flash types by sending an object instead of a string.

  @flashMessage(key: "error", text: "Invalid username and/or password").now()

  {{#flashMessage}}
  <div {{bind-attr class=message.key}}>
    {{message.text}}
  </div>
  {{/flashMessage}}
ryanto commented 10 years ago

Updated readme with controller instructions: https://github.com/ryanto/ember-flash-message#controller

michaelrkn commented 10 years ago

On #5 @ryanto you say "I think anytime you are using the flash message from a controller it should be instant (and not on the next route change). Otherwise it's probably an indictor your logic should be moved into a route."

I'm not understanding why you think this should be the case. In the README's example:

App.PostController = Ember.ObjectController.extend({
  needs: ['flashMessage'],

  actions: {
    save: function() {
      var flashMessage = this.get('controllers.flashMessage');

      this.get('model').save()
        .then(function() {
          flashMessage.set('message', 'Blog post saved!');
        });
    }
  }
});

it seems perfectly logical to add:

App.PostController = Ember.ObjectController.extend({
  needs: ['flashMessage'],

  actions: {
    save: function() {
      var controller = this;
      var flashMessage = this.get('controllers.flashMessage');

      this.get('model').save()
        .then(function() {
          flashMessage.set('message', 'Blog post saved!');
          controller.transitionToRoute('somewhereElse');
        });
    }
  }
});

as I often want to move the user to another page after successfully saving. But you seem to be saying that if I ever add a transition to a controller action, I should move the action and define it on the route. That feels weird and arbitrary - how do I know where to look for actions if they can be defined in multiple places?

Regardless, I'd expect that no matter where you set the flash message, it should behave the same, so it feels wrong to me that when it's set in the controller, it displays instantly, but when it's set in the route, it's displayed after the next transition.

On both of these points, I could totally be missing something, as I'm relatively new to Ember. If so, please enlighten me!

Thanks :)

ryanto commented 10 years ago

Controller setting is a new concept so I am open to changing it. However, handling actions inside of a controller that cause:

1) Data to be set for the next page/transition. 2) The application transition routes.

seems like too much responsibility for the controller. In Ember controllers handle presentation and state for a single object or collection. Controllers shouldn't know about or depend on other routes. The router's job is to handle setup and transition between the different states of your application.

It makes most sense in Ember that if you are setting data for another page and then transitioning to that page this be handled from within a route. To answer your question: how do I know where to look for actions if they can be defined in multiple places? The answer is generally anything that causing application/state change will be in the router. Anything that is local to a controller/outlet will be in the controller

I do agree with you about having the same API and behavior from both route/controller. Seems to follow the path of least surprise.

michaelrkn commented 10 years ago

Just FYI, this prompted me to start a thread on the Ember forums about this, and I am now enlightened ;)

minirobotdan commented 10 years ago

Hi guys, so are we saying that setting the message in the route before calling transitionTo should currently work?

Ignoring the custom message format (doing a similar hack mentioned above to send more complex data), this doesn't seem to work, but it does if I drop the transition...

merchantRecord.save().then(function() {
    _this.flashMessage({ message: 'The new merchant has been saved successfully.', success: true});
    _this.transitionTo('merchants');
  }, function(err) {
    _this.flashMessage({ message: 'Sorry, there was an error: ' + err.message, danger: true});
    console.error(err);
  });
ryanto commented 10 years ago

Hi minirobotdan,

Can you open a new ticket and create a jsbin/test case that reproduces this error. I think its unrelated to what this original/closed issue is currently about.

Thanks

minirobotdan commented 10 years ago

Hi Ryan, thanks will do.