James Parsons James Parsons - 2 months ago 13
Ajax Question

Returning a flash message for validation and succes from AJAX from submission using Laravel

I am of the understanding after doing research that JSON is used however I am unsure of the processes. The code below is my AJAX the console log after.done is not currently working however it was working when I had success as part of the AJAX object.

AJAX

$(document).on('click', '#button', function() {
var wrap = $(this).closest('div.form_wrap');
wrap.find('form').each(function() {

var id = $(this).prop('id');
var arr = jQuery.makeArray( "#"+id );
var url = $(this).attr('action');
var type = $(this).attr('method');
var i = $('#'+id); // Or just $(this)
var data = i.serialize();

// setup on submit
i.submit(function(event) {
event.preventDefault();
var formElem = $(event.currentTarget);

console.log(data);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

$.ajax({
type : type,
url : url,
data : data,
dataType : 'json',
encode : true
})
.done(function(data) {
console.log(data);
});
});

i.submit();
});
});


Controller

public function store(Request $request)
{

//validate
$this->validate($request, array (
//'exercise' => 'required|unique:workout_goals,user_id,NULL,id,exercise,'.$request->exercise,
//'reps' => 'required|integer',
//'exercise' => 'required|unique:workout_goals,exercise,NULL,id,user_id,'.$request->user_id,
));

//store
$post = new workout_shared;
$post->date = $request->date;
$post->user_id = $request->user_id;
//$post->shared_id = $request->shared_id;
$post->exercise = $request->exercise;
$post->weight = Input::get( 'weight' );
$post->reps = $request->reps;
$post->sets = $request->sets;

//save
$post->save();


//session flash message
Session::flash('success','Workout shared!');

//redirect


return back();
}


Thanks

Answer

$.done will only be called after a successful ajax call, so you are probably receiving an error while calling that url. Use $.fail to catch this error:

$.ajax(...)
 .done(function(){ console.log("Done!"); })
 .fail(function(jqXHR, textStatus, errorThrown){ 
    console.log("Fail!", jqXHR, textStatus, errorThrown); 
 });

Setting a Session::flash() will store this message in the session for the next http request, to retrieve this message use this on the next page displayed:

Session::pull(...)

However as you are calling with ajax you will need to return the message as JSON as you said. I would also recommend something along the lines of this to deal with your save method, and then implement either a flash message or json depending on how the method is called:

...

// Save 
$result = $post->save(); // return a boolean for success/fail
$message = $result ? "Workout shared!" : "Workout sharing failed!";

// Response
if ($request->ajax())
{
    // Ajax response, will translate to JSON
    return new Array(
       'Success' => $result,
       'Message' => $message
    );
}

// Regular Http response
Session::flash('save-response', $message);

// Redirect
...

A further step would be to extract the entire response section of this code to a new method, which could then also be used after validation, such as:

WorkoutSaveResponse($result, $message)