In controller I have a method, where I validate request. I have and custom error, see please code:
public function createComment(Request $request) {
$request->validate(['body' => 'string|min:10', 'type' => 'integer']);
if($this->lastComment(Auth::user()->id)) {
return response()->json(['errors' => 'Please try after 24 hours..'], 422);
} else {
$comment = Comment::create($request->all());
return $comment;
}
}
In vue I have axios:
axios.post('/createReview', {
body: this.body,
user_id: this.user_id,
type: this.type,
}).then(response => {
this.$emit('created', response.data);
}).catch(error => {
this.isLoading = false;
this.flash(error.response.data, 'error');
});
How I can correctly send these errors on component flash? When I get error on component I get [Object object]. I use this flash package: https://www.npmjs.com/package/vue-flash-message
That component will only render one message at a time and you are passing it an object.
this.flash(error.response.data.errors, 'error');
Related
I'm having problem in storing data in laravel, what I have done is created a request for using php artisan make:request and add fillable to my Model then added the process to the Vue component.
I also add v-model="form.name" and #click="submit" to the button for the form process.
In the end I am getting this 505 internal server error
I have also added <meta name="csrf-token" content="{{ csrf_token() }}"> to my app.blade.php
Is there a way to fix this and post my data successfuly?
Vue:
<script>
export default {
data(){
return{
form: {
job_name: null,
job_description: null,
vacants: 0
}
}
},
methods: {
submit(){
axios.post('/job_postings', this.form)
.then(function (response){
console.log(response);
})
.catch(function (error){
console.log(error);
});
}
}
}
</script>
Controller:
public function store(JobPostingRequest $jobPostingRequest, JobPosting $jobPosting)
{
$posting = $jobPosting::create($jobPostingRequest->all());
return response()->json(['message' => 'Job Posting has been successfully saved', 'data' => $posting]);
}
Requests:
public function authorize()
{
return true;
}
public function rules()
{
return [
'job_name' => 'required',
'job_description' => 'required',
'vacants' => 'required'
];
}
Model:
class JobPosting extends Model
{
use HasFactory;
protected $fillable = [
'job_name',
'job_description',
'vacants'
];
}
Routes/Web.php:
Route::resource('job_postings', JobPostingController::class);
You can get all values from your request with ->validated() method and create JobPosting from there.
use App\Models\JobPosting;
if($posting = JobPosting::create($jobPostingRequest->validated())){
return response()->json(['message' => 'Job Posting has been successfully saved', 'data' => $posting]);
}
return response()->json(['message' => 'Job posting failed.']);
Try this instead your store function.
vue function:
sendData() {
this.isLoading = true;
const postData = {
data: this.items,
};
var self = this;
axios.post(this.postUrl, postData).then(function (response) {
console.log(response.data);
self.isLoading = false;
});
this.items = [];
},
Laravel controller:
public function store(request $request)
{
foreach ($request->data as $data) {
$serie = [];
$serie = ['imei' => $data['serie']];
$imei = new Imei([
'imei' => $data['serie'],
'status_id' => 1,
'sucursal_id' => $data['sucursal'],
'equipo_id' => $data['equipo']
]);
$validator = Validator::make($serie, [
'imei' => 'unique:imeis,imei|digits:15',
]);
if ($validator->fails()) {
// Here I need to build the response of every imei with its validation error
} else {
$imei->save();
}
}
return >Here I want to return the errors back to vue
}
my vue app sends to laravel trough axios an array of objects that looks like this [{imei:xxxx,sucursal_id...},{imei:xxxx,sucursal_id...}] I need to validate imei is unique and save it, and if error return errors in the same way [{imei:xxxx,errorMsg: 'already exist in DB'}]. but I can't find the proper way to do it.
Basically you want to customize your errorbag right ? try this one out. Add this inside your fail condition. Let me know if it works.
$err = [{imei:xxxx,errorMsg: 'already exist in DB'}];
foreach ($validator->errors()->toArray() as $error) {
foreach($error as $sub_error) {
array_push($err, $sub_error);
}
}
return ['errors'=>$err];
Before laravel 5.5 I used a form request like this with a customized format :
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
class StoreProductRequest extends FormRequest
{
public function authorize ()
{
return true;
}
public function rules ()
{
return [
'title' => 'required',
'desc' => 'required',
];
}
public function response (array $errors)
{
return response()->json($errors, 200);
}
protected function formatErrors (Validator $validator)
{
$result = ['success' => false, 'msg' => $validator->errors()->first()];
return $result;
}
}
Means when an error occured, only the first error returned as a json format like this :
{
"success" : "false",
"msg" : "title field is required "
}
But seem that in laravel 5.5 in this way could not format error like this.
Now I want to return error exactly same format I mentioned above in json format but I do not know How can
This functionality was changed in Laravel 5.5. From the upgrade guide "A Note On Form Requests":
If you were customizing the response format of an individual form request, you should now override the failedValidation method of that form request, and throw an HttpResponseException instance containing your custom response
Your updated Form Request might look something like this (pseudo-code, not tested):
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
class StoreProductRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'title' => 'required',
'desc' => 'required',
];
}
public function failedValidation(Validator $validator)
{
throw new HttpResponseException(
response()->json(['success' => false, 'msg' => $validator->errors()->first()], 400)
);
}
}
protected function formatErrors (Validator $validator)
{
$result = ['success' => false, 'msg' => $validator->errors()];
return $result;
}
Expanding on #Aken Roberts answer. Since this is an error response for a form, I use the error key (input field name) to display the error beside the input.
You can get the first error key from the keys method. With Laravel 5.7 this works as expected:
public function failedValidation(Validator $validator)
{
throw new HttpResponseException(
response()->json([
'success' => false,
'error' => (object) [
$validator->errors()->keys()[0] => $validator->errors()->first()
]
], 400)
);
}
I have problem. I use event: https://github.com/musonza/chat/blob/master/src/Messages/MessageWasSent.php
In my controller:
public function sendMessage(Conversation $conversation, Request $request) {
$v = Validator::make($request->all(), [
'message' => 'required|string|max:4000',
]);
$user = User::find(Auth::id());
$conv = Chat::conversation($conversation->id);
Chat::message($request->message)
->from($user)
->to($conv)
->send();
event(new MessageWasSent($request->message));
}
I get error:
Type error: Argument 1 passed to Musonza\Chat\Messages\MessageWasSent::__construct() must be an instance of Musonza\Chat\Messages\Message, string given..
In my app.js:
send(){
if(this.message.length != 0 && this.message.length <= 4000) {
this.chat.message.push(this.message);
this.chat.user.push(this.user);
this.chat.time.push(this.getTime());
axios.post('/sendMessage/' + this.convId, {
message: this.message,
})
.then(response => {
console.log(response);
this.message = '';
})
.catch(error => {
console.log(error);
});
}
}
Routes:
Route::post('sendMessage/{conversation}', 'Chat\ChatController#sendMessage')->name('chatsend');
How I can fix this error?
$message = Chat::message($request->message)
->from($user)
->to($conv)
->send();
event(new MessageWasSent($message));
As the error says the event constructor requires an instance of Musonza\Chat\Messages\Message rather than a string,
I want to return a 401 error with a message if an user is not logged in. Here is my filter and the route to which it will be applied:
Route::filter('auth', function() {
if (!Auth::check())
{
return Response::json(array('flash' => 'Please log in.'), 401);
}
});
Route::get('/books', array('before' => 'auth', function() {
...
}));
I copied the code from a tutorial, so basically it should work. But I am getting this error:
"NetworkError: 500 Internal Server Error - http://localhost:8000/books"
{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":
"Call to undefined method Illuminate\\Http\\Response::json()","line 42"
Is it not possible to return JSON objects using a filter?
Edit:
I have the same response in one of my Laravel controllers and it works.
You can achieve in Laravel 4 this by using use Illuminate\Support\Facades\Response - documentation. Take a look at this simple code snippet - return Response::json([]);.
Usage in filter:
Route::filter('auth', function() {
if (!Auth::check()) {
return Illuminate\Support\Facades\Response::json([
'flash' => 'Please log in.'
], 401);
}
});
Usage in controller:
namespace App\Controllers;
use Illuminate\Support\Facades\Response;
/**
* Class ReportController
* #package App\Modules\Moderation\Controllers
*/
class ExampleController extends BaseController
{
// ################### class methods // ###############################
/**
* Create post action
* #return mixed
*/
public function someAction()
{
return Response::json([
'id' => 1337,
'name' => 'Bob',
'gender' => 'male'
]);
}
}
Try replacing this line :
return Response::json(array('flash' => 'Please log in.'), 401);
with this one :
return Response::json(array('flash' => 'Please log in.', 401));
I belive the jsno method accepts an array, an you were providing an array and a second parameter.
I don't know why I can use Response.json() in my controllers, but not in my filters. But in the API I saw JsonResponse and that worked for me:
return JsonResponse::create(array('flash' => 'Please log in.'), 401);