Validate and store data in Laravel with axios - json

I am using React\NextJS as forntend and Laravel as backend,
Storing data with Axios post as per below,
const storeExpense = async (expenseData) => {
const response = await axios.post('/api/expenses/store/', {expenseData})
return response.data;
}
Now this will be sent as a JSON object to Laravel, I am not sure how can I validate and store this JSON object data to MySQL.
Earlier I was using Jquery AJAX where it was easy to store with Request validation and then with create.
Below is the request payload to the backend,
{"expenseData":{"expense_description":"React","expense_date":"2022-17-4","expense_amount":"123","expense_tax_amount":"14.15","expense_note":"given","expense_receipt_number":"Ok no","taxgroup_id":1,"paymentoption_id":1,"vendor_id":1,"accountcustomtype_id":2,"submit":null}}
Below was Controller and Model, used when sending data as Form
//Controller
public function store(StoreExpenseRequest $request)
{
Expense::storeExpense($request);
return response()->json([
'val' => 1,
'msg' => 'Success',
]);
}
//Model
public static function storeExpense($request)
{
Expense::create([
'vendor_id' => $request->vendor_id,
'accountcustomtype_id' => $request->accountcustomtype_id,
'expense_description' => $request->expense_description,
'expense_date' => Carbon::parse($request->expense_date)->format('Y-m-d'),
'expense_amount' => $request->expense_amount,
'taxgroup_id' => $request->taxgroup_id,
'expense_tax_amount' => $request->expense_tax_amount,
'paymentoption_id' => $request->paymentoption_id,
'expense_receipt_number' => $request->expense_receipt_number,
'expense_note' => $request->expense_note,
]);
}
But now this doesn't work with JSON data,
How can I achieve this with Axios JSON data?
Thank you,

It was resolved by changing Axios request Data,
await axios.post('/api/expenses/store/', expenseData)

Related

Validate all JSON requests in Laravel

I am making a registration function with a RegisterRequest request class which should validate the request:
public function register(RegisterRequest $request)
{
//
}
The request validation (RegisterRequest) looks like this:
<?php
namespace App\Http\Requests\Api\User;
use App\Http\Requests\Request;
class RegisterRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true; // TODO: should secure this.
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required',
'email' => 'required|email|unique:users,email',
];
}
}
But I get the error that name and email are missing, I think this is because the request is send in JSON. How can I make this request validate the JSON input I am giving? Thanks in advance.
The way I am making the request:
handleSubmit (data) {
// Register User
this.$http
.post('/api/user/register', data)
.then(response => {
console.log(response)
// Clear form
// Show snackbar
})
.catch(error => {
console.error(error)
})
.finally(
// Update items in DataTable
console.log(data)
)
}
When I console.log(data); it shows me this:
{"name":"asdsfsdf","email":"sdfsfd#sdfs.com"}
when I try to validate like this:
$validator = Validator::make($request->json()->all(), [
'name' => 'required',
'email' => 'required|email|unique:users,email',
]);
It works, but I want to separate this logic from the controller.
Based on your comment, you're not sending the data correctly to the server --- you're sending it as an array key. In your AJAX/request call, send data as following (I'm using axios library as demo, but the schema can be applied in jquery or other js tools as well):
axios.post('/link/to/web/route', {
name: 'my name',
email: 'my email',
}).then(response=>{
alert('Data sent with success!')
}).catch(error=>{
alert('Error has occurred. Please check browser console');
console.log(error)
})
I managed to fix it by using the prepareForValidation method (https://laravel.com/docs/7.x/validation#prepare-input-for-validation):
protected function prepareForValidation()
{
$this->merge([
'name' => $this->json('name'),
'email' => $this->json('email')
]);
}
The rules function now successfully validates the JSON input.

Read json response from controller to Axios Catch section - Laravel Vue Axios

I have a method that captures the information sent by the vue view (Profile.vue) through a PUT generated by Axios, the problem lies in the following, when the data is updated (using the myProfile method of the UserController), axios captures the information of the return in json from the method, and the success message is shown, but when there is an error, Axios does not capture the error json information and alleges the following:
Uncaught (in promise) TypeError: Cannot read property 'status' of undefined
I understand that you are alleging to me by the variables that I have in the catch section of Axios that do not have information.
myProfile code (UserController)
$profile = User::find(Auth::user()->id);
$profile->firstname = $request->firstname;
$profile->lastname = $request->lastname;
$profile->gender = $request->gender;
$profile->description = $request->description;
if($profile->update())
{
return response()->json([
'status' => 'Muy bien!',
'msg' => 'Datos actualizados correctamente.',
'cod' => 201
]);
}
else{
return response()->json([
'status' => 'Ocurrio un error!',
'msg' => 'Ocurrio un error al actualizar la informaciĆ³n.',
'cod' => 400
]);
}
Axios section of Profile.vue
axios.put('/dashboard/profile', value)
.then((response) => {
let title = response.data.status;
let body = response.data.msg;
this.displayNotificationSuccess(title, body);
})
.catch((response) => {
let title = response.data.status;
let body = response.data.msg;
this.displayNotificationError(title,body);
})
As I said before, when there is success in the controller, Axios reads and shows the message json, when there is an error, it does not.
Where am I failing that Axios can not show the erro json message coming from the controller?
I used Laravel 5.6, Vuejs 2 and Axios
In the catch callback, the argument is the error object, not the response object. Try this:
axios.put('/dashboard/profile', value)
.then((response) => {
let title = response.data.status;
let body = response.data.msg;
this.displayNotificationSuccess(title, body);
})
.catch((error) => {
let title = error.response.data.status;
let body = error.response.data.msg;
this.displayNotificationError(title,body);
})
SOURCE
First - you have to define in your backend that the second part is actually an error, otherwise axios will see it as a successful request.
You do that by putting an error status code as a 2nd argument to response()->json(json, code). You can see a list of status codes here.
Example:
return response()->json([
'status' => 'Ocurrio un error!',
'msg' => 'Ocurrio un error al actualizar la informaciĆ³n.',
'cod' => 400
], 400);
Second, axios .catch() returns an error, not the response. In order to get the response, you have to call err.response on it.
Example:
.catch((response) => {
let title = response.response.data.status;
let body = response.response.data.msg;
this.displayNotificationError(title,body);
})

React failing to parse a JSON object from server

I'm running into this error:
Uncaught (in promise) SyntaxError: Unexpected token [ in JSON at position 1
when I pass a JSON object containing an array of JSON objects to my component. The object structure is:
{ "arrayName": [{object},{object},{object}, etc...] }
I've run the JSON through a validator and it comes up clean but my api call always returns the same error.
export const api = 'http://localhost:8000'
export const headers = {
'Content-Type': 'application/json',
'Accept' : 'application/json',
}
export const getAll = () =>
fetch(`${api}/480.json`, { headers })
.then(res => res.json())
.then(data => data.events)
This is where it gets called in App.js:
componentDidMount() {
eventsAPI.getAll().then((events) => {
console.log(events)
this.setState({ events })
})
}
I'm not sure why I'm getting the error, I know I'm sending a valid JSON object, is the way I'm receiving it wrong? I can see in the network tab of the dev tools that the correct format is being passed and received. I just don't know where exactly I've gone wrong. This is the response logged from the server. I can see the XHR response in dev-tools but it's a bit big to post here 25+ objects.
You need to modify getAll to actually return something. As it is a fetch, you can just return that, which will return the promise.
export const getAll = () =>
return fetch(`${api}/480.json`, { headers })
.then(res => res.json())
.then(data => data.events)
Now wherever you use getAll be sure to call then:
getAll().then(data => console.log(data))

Built api routes in laravel 5.x

I'm new in larevel. I want to create route in api.php. It's my code in this file
Route::middleware('auth:api')->get('/api', function (Request $request) {
return response()->json([
'name' => 'Abigail',
'state' => 'CA'
]);
});
I need to return json but when I put url mysite.com/api/api and page redirect me to mysite.com/user. How I can avoid redirect I get correct url?
Remove auth middleware and try again like:
Route::middleware('api')->get('/api', function (Request $request) {
return response()->json([
'name' => 'Abigail',
'state' => 'CA'
]);
});
You're getting redirected because you're using the auth middleware and are not authenticated. If the route does not need authentication just do:
Route::get('/api', function (Request $request) {
return response()->json([
'name' => 'Abigail',
'state' => 'CA'
]);
});
Here is a another example to parse direct model.
Laravel 5.2
Route::middleware('api')->get('/api/users', function (Request $request) {
return \App\Users::all();
});
You will get a json object for all users table data.

Angular2 Http.Post - How to view webapi response

I'm new to Angular2/Typescript and I'm writing my first web application.
I'm trying to call a webapi using POST, it works, if I intercept the call using FIDDLER I can see the Json response.
Now, how I can log in the browser console the json ouput?
The code is this:
code call
var s = this.myService.doSearch();
s.subscribe(
data=> this.data = data,
error => this.errorMessage = <any>error
);
console.log(s);
service method
doSearch() {
var url = this.baseUrl;
return this.http.get(url)
.map(response => response.json())
.catch(this.handleError);
}
My question is: how and where I can view and manage the Json Output ?
Thanks
You need to console.log it after the async code is finished:
var s = this.myService.doSearch();
s.subscribe(
data=> {
this.data = data;
console.log(data);
},
error => this.errorMessage = <any>error
);
If you are debug or run your application in browser you can got to inspect and then move to the Network tab. In this tab select your POST Request and the go to the tab Response and voila there is your json Response
Edit:
To log all response data do this:
return this.http.get(url)
.map(res => res.json())
.subscribe(data => { console.log(data);})
.catch(this.handleError);
}
Try this this will print what you have in your returned observable .
var s = this.myService.doSearch();
s.subscribe(data=> {
this.data = data;
console.log(data);
},
error => this.errorMessage = <any>error
);
Always remember If you want to get data from observable.you need to subscribe it.
you can't log it like this console.log(s); because s returns an observable. you should subscribe and refer those data inside the subscribe .