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();
asked Jan 29, 2015 at 14:47

2 Answers 2

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
}
answered Jan 29, 2015 at 14:53
3
  • 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? Commented Jan 29, 2015 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. Commented Jan 29, 2015 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. Commented Jan 29, 2015 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.

answered Jan 29, 2015 at 15:32
5
  • 1
    This is kind of the same thing I said. But please don't use echo in controllers. that's a bad practice Commented Jan 29, 2015 at 15:36
  • 1
    Then instead of echoing you would use this: $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($response); ? Commented Jan 29, 2015 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. Commented Jan 29, 2015 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. Commented Jan 29, 2015 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). Commented Jan 29, 2015 at 16:16

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.