ONYX ONYX - 2 months ago 20
Ajax Question

laravel on saving model return json from validation

Hi I'm having a problem outputting my json information on saving method in the model. I get the following error -
UnexpectedValueException in Response.php line 397:
The Response content must be a string or object implementing __toString(), "boolean" given.
I do validation on the model while saving and in the validate method of the model I need to out put the json but I'm getting boolean instead of json object

Javascript:

submit: function(e) {

e.preventDefault();

var contact = this.model.save({
firstname: this.firstname.val(),
lastname: this.lastname.val(),
company: this.company.val(),
email_address: this.email_address.val(),
description: this.description.val(),
}, {success:function(response){ console.log(response)}, wait: true});


Contact Model:

class Contact extends Model
{
protected $table = "contacts";

protected $fillable = ['firstname', 'lastname', 'company', 'email_address', 'description'];

public static function boot() {
parent::boot();

static::creating(function($model) {

return $model->validate('POST');
});

static::updating(function($model) {
return $model->validate('PUT');
});

static::saving(function($model) {
return $model->validate('PUT');
});
}


public function rules($method)
{


switch($method)
{
case 'GET':
case 'DELETE':
{
return [];
}
case 'POST':
{
return [
'firstname' => 'required',
'lastname' => 'required',
'email_address' => 'required|email|unique:contacts,email_address',
'description' => 'requried'
];
}
case 'PUT':
case 'PATCH':
{
return [
'firstname' => 'required',
'lastname' => 'required',
'email_address' => 'required|email|unique:contacts,email_address,'.$this->id,
'description' => 'required',
];
}
default: break;
}

return [];
}

public function messages() {
return [
'firstname.required' => 'Please enter your first name.',
'lastname.required' => 'Please enter your first name.',
'email_address.required' => 'Please enter a email address.',
'email_address.email' => 'Please enter a valid email address',
'email_address.unique' => 'The email is not unique.',
'description' => 'Please enter a description.'
];
}


public function validate($method)
{
$data = $this->attributes;

// if( $data['slug'] === '') {
// // if the slug is blank, create one from title data
// $data['slug'] = str_slug( $data['title'], '-' );
// }

// make a new validator object
$v = Validator::make($data, $this->rules($method), $this->messages());


// check for failure
if ($v->fails())
{
// set errors and return false
// json here not return response it's always boolean true or false
return new JsonResponse(array('error' => true, 'errors' => $v->messages()));
}

// validation pass
return true; //new JsonResponse(array('errors'=>false));

}

public function errors() {
return $this->errors;
}

public function user() {
return $this->hasOne('App\User', 'email', 'email_address');
}
}


Saving the model:

public function update(Request $request, $id) {

$contact = Contact::find($id)->with('user')->first();
$contact->firstname = $request->get('firstname');
$contact->lastname = $request->get('lastname');
$contact->email_address = $request->get('email_address');
$contact->company = $request->get('company');
$contact->description = $request->get('description');

return $contact->save(); //return formatted json
}

Answer

According to your implementation of validation, you should change the following part (in Contact):

// check for failure
if ($v->fails())
{            
    // set errors and return false
    // json here not return response it's always boolean true or false
    return new JsonResponse(array('error' => true, 'errors' => $v->messages()));
}

To something like this:

if ($v->fails()) {            
    $this->errors = $v->errors();
    return false;
}

Then, from the Controller, try something like this:

// If validation failed

if(!$contact->save()) {
    return response()->json([
        'error' => true,
        'errors' => $contact->errors()
    ]);
}

// Contact created if reached here...
return response()->json(['error' => false, 'contact' => $contact]);

Also, check the Ajax-Request-Validation and Form-Request-Validation (Easier and Managable).


Note: Don't try to return any kind of HTTP Response from model. Returning the HTTP response is part of your application logic and model should not care about these.

Comments