1

Currently, I am using ajax to add an coupon to the cart. This requires a success/error message to display to the user. However, it seems that i'm unable to retrieve this error/success message without a redirect (something ajax does away with) and the message itself is always displayed on the next pageview.

Is there an easy way to work around this?

The message is set using this in the observer:

Mage::getSingleton('core/session')->setCouponCodeError($error);

This doesn't seem to work in the controller (after the event has been dispatched):

$message = Mage::getSingleton('core/session')->getCouponCodeError();
3

For ajax calls you need to return the error messages if any. It does not work with $session->addError(). The message you set with addError are picked up on the next page load.

You need to do something like this in your controller:

public function doSomeAjaxStuff()
{
    $response = array();
    $response['success'] = true;
    //do stuff here
    $response['something'] = 'Something';
    if (some error occurs) {
        $response['success'] = false;
        $response['message'] = 'Your error message here';
    }
    $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($response); 
}

And in your javascript code that handles the response from the ajax call do this:

if (!response.success) {
    alert(response.message);
    //or insert response.message somewhere in the dom
}
  • That's lame. I guess i'll have to rework the observer. Is it possible at all to return this error message string from the observer to the controller? – easymoden00b Jan 29 '15 at 14:58
  • 1
    You can regiter it using Mage::register() then retrieve it with Mage::registry but only if the observer action is executed in the same request as your controller. – Marius Jan 29 '15 at 15:11
  • The dispatch event is immediately before I would call the registry. Although it does not appear to function. Thanks though, any other ideas? Accepted your answer. – easymoden00b Jan 29 '15 at 15:19
1

The reason why Mage::getSingleton('core/session')->addError() isn't working for you is because it makes a session variable. This is server side language. ( I don't know how to explain that any better :l)

You can still use Ajax.

In a controller, with no rendered layout. You can put the response logic there. Then echo the message.

Then your response will have the echoed message.

/*In Controller */
public ajaxErrorAction() {
    $error = "This is an error";
    $post = $this->getRequest()->getPost();
    if($post['is_error'] ==  "yes") { echo $error; }
}

/* Ajax */
data = {is_error : "yes"};
$.ajax({
    type: "POST",
    url: "<?php echo $this->getUrl('module/controller/ajaxerror') ?>",
    data : data,
    success: function (response) {
          alert(response);
    }
});

Im sure there is a better way to do this. But that is what I have done in the past.

  • 1
    This is kind of the same thing I said. But please don't use echo in controllers. that's a bad practice – Marius Jan 29 '15 at 15:36
  • 1
    Then instead of echoing you would use this: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($response); ? – Aedonis Jan 29 '15 at 15:37
  • I'm aware, this is actually what my original solution looked like, however, another member of the team developed a large observer that is used to determine the type of error and assign an error message -- which i'm attempting to pick up and display with a controller and display via ajax. Thanks though i'll suggest a redesign. – easymoden00b Jan 29 '15 at 15:41
  • @Marius and Roshni, do you think it'd be acceptable practice to simply move the observer methods into the controller (and fiddle around with return statements of course). This will bloat up the controller but I assume the functionality would keep this into the correct scope. – easymoden00b Jan 29 '15 at 16:09
  • 1
    I think so. I don't see a problem with bloated controllers if that's the only way to do it. There is the option of putting the business logic in a block class and calling the block in the controller like this: $block = Mage::app()->getLayout()->createBlock('yourmodule/yourblock'); $result = $block->printError();. This will help with the bloat (funny :D). – Aedonis Jan 29 '15 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.