I'm building my first API and I have this nightmare scenario where I see myself defining the same request data in multiples places. How are people maintaining their key/value payloads?
Here's my VueJS component on the client side:
<script>
export default {
data() {
return {
name: '',
description: '',
selectedHeader: '',
}
},
computed: {
businessUrl() {
return this.name.replace(/[^A-Z0-9]+/ig, '') + '.test.com';
},
},
methods: {
preview() {
let data = {
'name': this.businessUrl,
'description' : this.description,
'selectedHeader': this.selectedHeader
};
axios.post('/builder/preview', data)
...
</script>
Server-side:
public function preview()
{
$validatedData = request()->validate([
'name' => 'required',
'description' => 'string',
'selectedHeader' => 'required',
]);
$business = new Business;
$business->name = request('name');
$business->description = request('description');
$business->header = request('selectedHeader');
return view('business', compact('business'));
}
If I want to change the 'name' field that is posted on my route I have to do it in up to 5 places if I include references in my HTML. Any patterns that people have developed to avoid this duplication?
Related
i am making a GET api in Laravel the api in postman works great but when i use it in Laravel to fetch specific data they come undefined. This is the api.php route:
Route::get('list',[GetController::class,'getValues']);
This is the GetController :
function getValues()
{
return response()->json([ValuesResource::collection(Order::all())], 200);
}
This is the ValuesResource :
public function toArray($request)
{
return [
'order_number' => $this->order_number,
'client_id' => $this->client_id,
'description' => $this->description,
'client' => new ClientResource($this->client),
];
}
This is the ClientResource :
public function toArray($request)
{
return [
'name' => $this->name,
'age' => $this->age,
'salary' => $this->salary,
];
}
And this is the blade JQuery code :
async function getData() {
const apiUrl = "http://127.0.0.1:8000/api/list";
const response = await fetch(apiUrl)
const barChatData = await response.json()
console.log(barChatData);
const salary = barChatData.map((x) => x.salary)
//console.log(barChatData.map((x) => x.salary))
const age = barChatData.map((x) => x.age)
const name = barChatData.map((x) => x.name)
employeeSalaryData = salary
employeeAgeData = age
employeeLabel = name
}
In postman i get this result:
[
[
{
"order_number": "b7f55e7ce5",
"client_id": 1,
"description": "order1",
"client": {
"name": "Mr. Omari Schaefer DVM",
"age": "29",
"salary": "150"
}
}
]
]
While on browser they come undefined, if i do just
console.log(barChatData);
I get this array
[Array(1)]
0
:
Array(1)
0
:
{order_number: 'b7f55e7ce5', client_id: 1, description: 'order1', client: {…}}
length
:
1
So the values are coming but i cant fetch them with specific row.
Your code seems to be working fine but need a couple things to change as your fetched data is there.
there is array inside barChatData so map it like this:
const age = barChatData[0].map((item) => {
return item.client.age;
});
const name = barChatData[0].map((item) => {
return item.client.name;
});
const salary = barChatData[0].map((item) => {
return item.client.salary;
});
How isit possible to throw an custom Error from Laravel in Inertiajs.vue without redirecting then?
Vue Component:
Inertia.post('company-organisations-create', {
name: this.newOrganisation.name,
description: this.newOrganisation.description
},
{
preserveScroll: true,
onSuccess: (page) => {
return Promise.all([
window.Toast.success(this.$page.props.toast.message),
this.newOrganisation.name = '',
this.newOrganisation.description = '',
])
},
onError: (errors) => {
window.Toast.error(errors.toastMessage)
}
});
LaravelController():
public function createOrganisations(Request $request)
{
try {
CompanyOrganisations::create([
'company_id' => $companyID,
'name' => $orgName,
'description' => $orgDescription,
]);
} catch(Excpetion) {
// Create Inertia Error 'onError'
/* As example with json response
return response()->json([
'message' => 'ups, there was an error',
], 403); */
}
return Redirect::route('company.organisations',
)->with([
'toastMessage' => 'Organization created!'
]);
}
As Im not able to receive json format in Inertia request, I need to throw a error in Inertiajs.vue Component.
Thank you very much.
Try this:
try {
// ...
} catch(Excpetion) {
return redirect()->back()->withErrors([
'create' => 'ups, there was an error'
])
}
The errors should be received onError
onError: (errors) => {
window.Toast.error(errors.create)
}
I am using Laravel 8, VueJS and Axios for my application then every time I try to fetch all records from my database it returns an error with status code 500. Even though when fetching the data using Postman/Insomnia it returns the data without an error.
I tried to empty the table where it fetches the data the error disappears and it returns empty data with status code 200.
Store Module:
import axios from 'axios'
export default {
namespaced: true,
state: {
courses: [],
teacher: '',
},
getters: {
allCourses(state) {
return state.courses
},
},
actions: {
async fetchAllCourses({ commit }) {
const response = await axios.get('teacher/course-management/list')
console.log(response.data.data)
commit('SET_COURSES', response.data.data)
}
},
mutations: {
SET_COURSES(state, courses) {
state.courses = courses
}
}
Controller:
public function fetchAllCourses() {
try {
$courses = Course::all()->sortBy('id');
$data = $courses->transform(function ($course) {
// ! Get teacher id
$teacherId = $this->user->teacher->id;
// ! Get teacher name by id
$teacherName = $this->getTeacherName($teacherId);
return [
'id' => $course->id,
'teacher_id' => $course->teacher_id,
'teacher' => $teacherName,
'section' => $course->section,
'code' => $course->code,
'status' => $course->status,
'image' => $course->image,
];
});
return $this->success('Request success', $data);
} catch (\Exception $e) {
return $this->error($e->getMessage(), $e->getCode());
}
}
Problem solved.
public function fetchAllCourses() {
try {
$courses = Course::all()->sortBy('id');
$data = $courses->transform(function ($course) {
return [
'id' => $course->id,
'teacher_id' => $course->teacher_id,
'teacher' => $this->getTeacherName($course->teacher_id),
'section' => $course->section,
'code' => $course->code,
'status' => $course->status,
'image' => $course->image,
];
});
return $this->success('Request success', $data);
} catch (\Exception $e) {
return $this->error($e->getMessage(), $e->getCode());
}
}
I am trying to validate in my controller a request of nested parameters but I can't get it working. I did find a few resources online and tried different things with no success.
This is the script that sends the data to the controller:
var fieldsValuePair = {
type: this.history.type
};
axios.get('/app/admin/cms/clients/processActivity', {
params: {
fieldsValuePair: fieldsValuePair,
hid: this.history.hid
}
})
.then((response) => {})
.catch(error => {
this.errors = [];
this.errors = error.response.data;
console.log(this.errors);
});
This is my validation in my controller:
$this->validate($request, ['type' => 'required'] , ['activity-type.required']);
I want to say that if i add: type: this.history.type in my axios request just after hid: this.history.hid then the validation works correctly.
What I want to achieve is to have the type: this.history.type in the fieldsValuePair object and have this validate correctly in the controller.
I did find a solution but not sure if this would be the best one. At least it's working for me.
$rulesArray = [];
$fieldsValuePairArray = json_decode($request['fieldsValuePair'], true);
foreach ($fieldsValuePairArray as $key => $value) {
if($value == '')
$rulesArray[$key] = 'required';
}
$this->validate($request, $rulesArray , ['activity-type.required']);
i want to post ajax request using vue-resource this.$http.post request. it worked perfectly fine if i passed all validation rules but i want to get some validations if it fails. so far i keep getting 500 error if i don't fill out some input fields. it's hard for me to debug the error because it didn't appeared on the network tab.
here's what i've done so far
//my modal component
<script>
export default {
props: ['show'],
data() {
return {
input: {
id: '',
name: '',
address: '',
email: ''
},
errorInputs: {}
}
},
methods: {
createStudent() {
this.$http.post('/students', this.$data.input)
.then((response) => {
alert('added new row!)
}, (response) => {
console.log(response.data);
});
}
}
}
</script>
// my controller
public function store(Request $request) {
$validator = $this->validate($request,[
'id' => 'required',
'name' => 'required|unique:students',
'email' => 'required|unique:students|email',
'address' => 'required',
]);
if($validator->passes()){
Student::create($request->all());
return response()->json([], 201);
}
$errors = json_decode($validator->errors());
return response()->json([
'success' => false,
'message' => $errors
],422);
}
any helps and references would be appreciated. i am using laravel 5.3 and vue js 2
$this->validate() returns 422 error response alongside your validation errors, so you should get those errors in then() second callback (like you do now). Your vue component body should be like this:
{
data() {
// ...
},
createStudent() {
this.$http
.post('/students', this.input)
.then(this.handleSuccess, this.handleError)
},
handleSuccess(res) {
alert('student created')
},
handleError(res) {
if (res.status === 422) {
this.errorInputs = res.body
} else {
alert('Unkown error!')
}
}
}
Remember to add v-model="input.fieldName" properties to your inputs.
Remember to include your session token along with your post, unless of course you are disabling csrf tokens for that route.
Since Laravel 5.1 you can disable this in your verifytoken middleware
<?php namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as ...
class VerifyCsrfToken extends ... {
protected $except = [
'payment/*',
];
}