Return json value in inertia.
How can i return json response in inertia? I am using React. I don't want to use axios for this.
function handleSubmit() {
post(route('register.check-email'), {
onStart: () => setIsLoading(true),
onSuccess: (response: any) => {
console.log('User exists:', response);
},
onFinish: () => setIsLoading(false),
});
}
Route::post('/check-email', function (Request $request) {
$request->validate([
'email' => ['required', 'email'],
]);
$email = $request->email;
$checkIfEmailExists = User::where('email', $email)->first();
return redirect()->back()->with(['user_exists', $checkIfEmailExists ? true : false]);
})->name('register.check-email');
As one has yet responded, I'll pass on a couple of suggestions. But I don't use React, so this may not be helpful.
I would pass the true/false back as a prop and just read it in the onSuccess() function. So rather than returning with a redirect back -> with(), try something like:
$checkIfEmailExists = User::where('email', $email)->first();
$email_exists = $checkIfEmailExists ? true : false;
return Inertia::render( '/name_of_page', [ 'email_exists' => $email_exists ] );
Assuming you declared the prop in the component (this may be vue specific), then in the onSuccess() you should be able to read the prop, so:
onSuccess: () => {
console.log( prop.email_exists );
}
The details may vary, and if the component also has other props then you'd use the 'only' feature when requesting and passing back the data.
But even with your other approach, Inertia returns everything as json, so it should be there as part of the json already returned. See this for more info:
Hopefully someone with more knowledge about Inertia and React will give you a better answer.
@Max100 Hello! Thank you for the reply. But the problem here is the "/name_of_page" is not really a page, it is a component and not in the Pages folder so this won't work. I tried using redirect()->back()->with() as well but no luck. Using axios now.
@ap1234 @ap1234 In that situation, axios might be the better option. I sometimes use it for lookup components and for integrating fullcalendar into an inertia app.
You'd lose the automatic error handling of useForm(), but could still do validation on the server and use axios error handling to pick up the errors.
Because Inertia uses axios, you may not need to add it as a separate dependency and might still be able to just use the inertia router.post().
I think Inertia will recognize a standard JSON response (not an Inertia page) and handle it accordingly. So in your example, you might be able to do something like this:
function handleSubmit() {
router.post(route('register.check-email'), {
onStart: () => setIsLoading(true),
onSuccess: (response: any) => {
console.log('User exists:', response);
},
onFinish: () => setIsLoading(false),
});
}
and on the server:
Route::post('/check-email', function (Request $request) {
$request->validate([
'email' => ['required', 'email'],
]);
$email = $request->email;
$checkIfEmailExists = User::where('email', $email)->first();
$email_exists = $checkIfEmailExists ? true : false;
return response()->json( [ 'email_exists' => $email_exists ] );
If that works, you'd avoid the axios call and can use the automatic error handling of useForm(). Btw, be sure you use router.post() on the front end, rather than just the post() in your example.
One way or another, I'm sure you'll get it sorted out. Good luck!
@Max100 Hey! I tried your approach, but the route.post still returns 'All Inertia requests must receive a valid Inertia response, however a plain JSON response was received.' Below is how i used the router.post. I think I will use axios only as I don't have any option.
function handleSubmit(): void {
router.post(
route('register.check-email'),
{ email: data.email },
{
onStart: () => setIsLoading(true),
onSuccess: (response: any) => {
console.log('User exists:', response);
},
onFinish: () => setIsLoading(false),
},
);
}
@ap1234 Sorry about that, I was misinformed. Axios looks like the best option in this situation. Good luck!
I don't want to use axios for this.
Why? You could use the native fetch API or similar, but I assume you mean you want to use useForm's post() helper. But it's not designed for arbitrary data - it expects an Inertia response, possibly following a redirect.
An Inertia response is already JSON, but it has a specific structure understood by Inertia's router and form helpers. If you want to return custom JSON, don't use the form helper.
As for the backend, you return JSON like this:
return response()->json([
'foo' => 'bar',
]);
@JussiMannisto Thanks for the answer! Using axios kills the validation which comes by default with useForm. But i think i don't have any option other than using axios.
@ap1234 If you just need to pass custom data from the controller to the post() response, it can be done through Inertia's props. It just takes an extra step because the form endpoint redirects to another route (back to the form page).
The with() method flashes data to the session, where it's kept only until the next request — that is, until the redirection to the form page. You're trying to set a user_exists value, but the method is used incorrectly. with() takes either a key and a value, or an associative array:
// Option 1:
return redirect()->back()->with('user_exists', $checkIfEmailExists ? true : false);
// Option 2:
return redirect()->back()->with([
'user_exists' => $checkIfEmailExists ? true : false,
]);
Right now you're passing an array with two values and that won't work.
First fix the method call, then pass the flashed value to the form page as a prop:
Inertia::render('Your/Form', [
'user_exists' => session('user_exists'),
]);
Then you can read it from the response:
onSuccess: (response: any) => {
console.log('User exists: ' + response.props.user_exists);
},
@JussiMannisto Thank you for your response! But this won't work as 'Your/Form' is not in the Page Folder, it is a component. I did try it out. Thanks for your help!
@ap1234 I don't understand what you mean. When you return redirect()->back() in /check-email, it doesn't return a redirection to a "component". It returns a redirection to the route that rendered the form page — more accurately the URL in the Referer request header. If you pass a prop to Inertia::render() there, then it's available in the response props of the onSuccess callback.
@ap1234 I use axios js all the time and never have trouble with validation.
Please or to participate in this conversation.