inertiajs / inertia-laravel

The Laravel adapter for Inertia.js.
https://inertiajs.com
MIT License
2.07k stars 232 forks source link

Raw json response #103

Open sinnbeck opened 4 years ago

sinnbeck commented 4 years ago

I am unsure if this is somehow possible or if this is a feature request.

It would be wonderful if there was a simple way to return a JsonResponse from a controller manually. I can work around this, but it would be a nice feature :)

Something like


public function show($id)
{
    return Inertia::json(User::find($id));
}
reinink commented 4 years ago

I am curious, why do you want this? The whole idea behind Inertia is that it detects the request type (regular HTML request vs Inertia request), and then returns the proper response accordingly. Why would you want to always for a JSON repsonse?

sinnbeck commented 4 years ago

See that is a good question. I take a bit of liberties with inertia to make the user experience nicer.

Let me explain the setup: The page is a list of statistics for different projects. It only shows those you want to see. In the corner there is a select, which lets you add new projects to the list by selecting them. Now I could reload all statistics on the page when a new element is added, but I would rather just send a request to an endpoint to get data for just the added project and manually add it to the list with react. For now i just let inertia reload the page

If I had such an endpoint it would never have a page affiliated with it. It is just a classic show route that returns a JSON response.

I am well aware that the point of inertia is to have a more classic build website that just functions as a SPA, but I am mixing it to get the best of both worlds :)

Juhlinus commented 4 years ago

@Sinnbeck I apologize if I'm misinterpreting your use-case, but wouldn't this be solved pretty easily with Partial Reloads?

sinnbeck commented 4 years ago

@Juhlinus The issue would be that my index method does not have a 'prop' for a single project's data, only for all subscribed projects. Currently I am indeed using a partial reload, to reload the stats for all projects (but there is a difference in having to reload 20 projects or 1)

kiiya commented 4 years ago

@Juhlinus Another use case could maybe be polling? I had such a use case and had to return raw json.

claudiodekker commented 4 years ago

Yeah, polling would be a solution, I suppose.

While we're now talking more in lines of solving your issue instead of addressing your question, I'd still like to give my two cents: You could structure your statistics response in such a way that each project is keyed by it's id, and then on selection change, or on an interval, make a call to a Sanctum/Passport-configured JSON API endpoint (such as /api/v1/projects/{id}/statistics/summary) and hot-swap the partial data in the component.

Alternatively, you could go the Laravel Echo-way (read: websockets-way) and do that instead, but I think polling might be easier :)

Good luck!

diego-lipinski-de-castro commented 3 years ago

I think this would be nice to have. We use inertia because we are developing SPAs, sometimes we dont want a full component render, we are just making (for example) a multi-step form, in which, this would fit very well.

BenSampo commented 2 years ago

I had a requirement for this in my project. To get the page data as JSON I created the following function which I consumed via a hook.

The key parts are the headers which trigger a JSON response as opposed to a HTML response.

const { version } = usePage();

async function fetchInertiaPageJson(
    url: string
): Promise<AxiosResponse<Page<any>>> {
    return axios(url, {
        headers: {
            "X-Inertia": true,
            "X-Inertia-Version": version,
        },
    });
}
themahdavi commented 2 years ago

@reinink Use case could maybe be for example saving images of content by using tiptap headless text editor. i need endpoint that response json final url of image to content to save in img src tag to show them

ImSeaWorld commented 2 years ago

Thanks to @BenSampo I finally got it. idk what sort of voodoo magic he's talking about but for those curious:

PHP

namespace App\Http\Controllers;

use Inertia\Inertia;
use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        return Inertia::render('User/index', [
            'users' => User::all()
        ]);
    }
}

Vue

<script>
import { usePage } from '@inertiajs/inertia-vue3';

const { version } = usePage();

export default {
    name: 'Users',
    props: {
        users: Object,
    },
    data() {
        return {
            loading: false,
        };
    },
    methods: {
        customReload() {
            this.loading = true;

            this.axios.get('/users', {
                headers: {
                    'X-Inertia': true,
                    'X-Inertia-Partial-Component': 'User/index',
                    'X-Inertia-Partial-Data': 'users',
                    'X-Inertia-Version': version.value,
                }
            }).then(({data}) => {
                console.log(data.props.users);
            })
            .catch(console.error)
            .then(() => {
                this.loading = false;
            });
        },
    },
};
</script>

Honestly, we just need $inertia.reload to be a promise, or in some way other than a bunch of callbacks. Not a fan. Ben was just missing X-Inertia-Partial-Component and X-Inertia-Partial-Data.

mohitmamoria commented 1 year ago

I made this wrapper around form helper to work with JSON calls:

https://gist.github.com/mohitmamoria/91da6f30d9610b211248225c9e52bebe

baoanhng commented 9 months ago

I made this wrapper around form helper to work with JSON calls:

https://gist.github.com/mohitmamoria/91da6f30d9610b211248225c9e52bebe

Just in time.