wmluke / angular-flash

Flash messages for Angular JS
MIT License
159 stars 53 forks source link

flash messages on multiple pages is not working #28

Open SrividyaKasu opened 10 years ago

SrividyaKasu commented 10 years ago

When I have flash messages in consecutive views, flash message on second page is not shown. Please check the below code. flash to strategy also is not working(
flash.to('alert-1').info = 'Only for alert 1';) It seems like page 1 swallowing flash message destined to page 2.

Page 1

{{flash.message}}

Page 1 controller flash.success = 'Deletion was successful.';

Page 2

{{flash.message}}
aminal commented 10 years ago

You're dealing with different scopes. In it's current form, angular-flash cannot flash.to() a DOM element that doesn't exist (yet). If you attempt to flash.to() an element on the page of your current scope, you'll see that it is working.

I was having the same issue, so I simply created a catch-all alert (not assigning an id to the alert element) on the second page.

SrividyaKasu commented 10 years ago

@mark : Thanks for you response. Even catch all alert is not working on second page. If I remove {{flash.message}} div element in the first page, then flash message works in second page. Its like I can either one of the flash message, not both.

wmluke commented 10 years ago

Hi @SrividyaKasu,

Thanks for posting this issue. Can you provide more detailed HTML and JS snippets of page 1 and page 2 and controller 1 and controller 2?

Thanks, Luke

mahrton commented 10 years ago

Hi Luke and Mark,

I work for the same company as Srividya. I attempted to fix this problem and have a patch that seems to work and is compatible with the existing functionality. (As much as I can see.)

I've created a pull request please revise and perhaps approve if you find it useful.

Best regards Marton Tatai

wmluke commented 10 years ago

Hi Marton,

Thanks for the PR, but before we go there I'd like to get a better understanding of this issue.

Please include some more detailed template and controller examples so that I can dig deeper.

Thanks again, Luke

mahrton commented 10 years ago

Hi Luke,

Thanks for your reply. I've compiled a package with the example files. They are commented and I've deleted most of the content to make it simpler and more transparent. http://www.sendspace.com/file/azl4pa

If I've deleted too much or you need more information please let me know. Generally the problem is that when there is a message box on the page we are navigating away from the hooked $destroy event gets rid of the message we set in the controller before we navigate away from the page. That's what my PR attempts to fix. We want to keep the flash message until it is consumed on the next page. I suspect this library wasn't exactly intended to be used this way, but the changes in the PR don't "fix" this, it just provides a way to go around it.

Regards Marton

mahrton commented 10 years ago

Hi Luke,

I do not mean to rush you, I just wondered if you perhaps had a chance to look at the ZIP file I have sent, or you need more information from us?

Regards M

wmluke commented 10 years ago

Hi Marton,

Thanks for following up.

Admittedly, I've been preoccupied learning how to be a first time father. The online docs for these newborn platforms isn't so great ;-).

Fingers crossed, I'm hoping to get caught up this weekend.

Thanks again for contributing.

Luke

On Apr 16, 2014, at 2:01 PM, Marton Tatai notifications@github.com wrote:

Hi Luke,

I do not mean to rush you, I just wondered if you perhaps had a chance to look at the ZIP file I have sent, or you need more information from us?

Regards M

— Reply to this email directly or view it on GitHub.

mahrton commented 10 years ago

Haha, that is fantastic, congratulations! Take your time, first thing first.

Best regards M

mahrton commented 10 years ago

Hi Luke,

Is there any chance you will be able to review the pull request anytime soon?

Bests M

mren commented 10 years ago

Any updates on this? I have the same issue. I'm having flashes in both views (basically its the same view with a $route.reload()). Its the Edit page of a model. When I want to update the model I set a flash and reload the page to reduce the state changes in the controller.

The flash on the first page receives the message and directly cleans in on the destroy event. The second flash never sees the message.

The code looks a bit like this


function Controller($scope, $route, flash) {
  $scope.submit = function() {
    // Model update omitted for brevity.
    flash.success = 'Model updated';
     // Easier to reload all models and the changed
    // dependencies than to keep track of state.
    $route.reload();
  };
}
mahrton commented 10 years ago

Hi Mark,

If you want you can clone my branch then use it something like this.

function Controller($scope, $route, flash) { $scope.submit = function() { // Model update omitted for brevity. flash.success = 'Model updated'; flash.cleanOnReload = false; // Easier to reload all models and the changed // dependencies than to keep track of state. $route.reload(); }; }

It will carry your message on to the next page or until reload.

Bests M.

wmluke commented 10 years ago

Hi Folks,

Sorry for the radio silence. I've been pondering how to best support this behavior.

Initially, I envisioned angular-flash as a simple realtime pub/sub pattern with little to no state and persistence.

But it seems that you guys would like to use it more like the HTTP session flash pattern popularized by rails flash. With Rails, the flash message is persisted within the HTTP session and then displayed and removed with the next HTTP request. So Rails flash involves state and leverages the the HTTP request cycle to determine when to show and remove the persisted flash.

In contrast, angularjs apps (single page HTML5 apps in general) don't have a common request cycle and session state to leverage. For routing, some apps use angular-route, others use angular-ui-router, and others don't use routing at all. Likewise for session, some apps use localstorage, some use IndexDB, some use in-memory hashes, and some don't have a session at all.

Admittedly, the name angular-flash implies that it should operative like a traditional HTTP web app flash service. And I'm dreaming up better ways to support this behavior in v2.0.

In the meantime, I can bake-in something like flash.on(event), where event can be either an angular scope event, such as $routeChangeSuccess, $destroy, and $stateChangeSuccess; or a callback with parameters: notify, type, and message.

Here are some examples:


// Publish this `success` alert after the next `$routeChangeSuccess` event.
flash.on('$routeChangeSuccess').success = 'Hello from the previous page';

// Roll your own event callback: Publish this `info` alert after this scope is destroyed
function onDestroy(notify, type, message) {
    $scope.$on('$destroy', function () {
        $timeout(notify);
    });
}
flash.on(onDestroy).info = 'bye bye from about page';

Thoughts?

Thanks again for your patience and continued feedback, Luke

nikhilvij commented 10 years ago

Hey @wmluke I also intended to use it for multiple pages. Did you end up implementing this, or is there any workaround to do this right now?

StevenClontz commented 10 years ago

My solution is to have a separate HeaderCtrl for all things common across my app: navbar, sidebar, and flash messages. Then, even when my route (well, state since I'm using ui-router), changes, the messages persist since that part of the page isn't affected.

EDIT: More details.

<body>
<div ng-controller="HeaderCtrl">
<nav><!-- etc. --></nav>
<div id="messages">
  <div flash-alert active-class="in alert" class="fade">
    <span class="close" ng-click="hide()">
      &times;
    </span>
    <strong class="alert-heading">FYI.</strong>
    <span class="alert-message">{{flash.message}}</span>
  </div>
</div>
</div>
<div id="main" ui-view></div><!-- or ng-view if you prefer -->
</body>
app.controller('SomeCtrl', ['flash', function (flash) {
      flash.error = 'Check yourself before you wreck yourself.';
}]);

Actually, there's no reason to have the separate control: as long as the flashAlert directive is outside your uiView or ngView, it shouldn't be affected when moving from view to view.

davetron5000 commented 10 years ago

Just to chime in, I ended up using @StevenClontz's solution and it worked well. This feels more like the "correct" way to do it, as opposed to some blob of data persisting throughout navigation events.

colinmutter commented 9 years ago

Instead of always having to use angular-flash in a high-level scope (above the view/ui-view), why not retain the messages in the angular-flash service, like in angular-flare? It wouldn't force a particular design pattern and would let one access the flash messages without the worry of them getting nuked with the directive.