Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

hjortur17's avatar

Trying to load services with booking

Hi, I'm trying to get services by using ->with, but it doesn't load the services. I have on my Booking model a belongsToMany relationship.

So this is what I'm doing, I have a VUE search input which looks up Bookings by there booking ID, and that's open a link using window.href.

Here is my code:

MODEL

public function services()
{
	return $this->belongsToMany('App\Service');
}
CONTROLLER

public function search(Request $request)
	{
		$booking = Booking::where('id', '=', $request->bookingId)->with('services')->first();

		return $booking;
	}
SEARCHBOOKING.VUE

<template>
	<div>
		<input class="appearance-none block w-full bg-gray-300 text-gray-700 border border-gray-200 rounded py-2 px-4 focus:outline-none focus:bg-white focus:border-main transition" type="number" placeholder="Leita af bókun" v-model="bookingId" @keyup.enter="search">
	</div>
</template>

<script>
export default {
	data() {
		return {
			user: window.App.user,
			bookingId: ''
		}
	},

	methods: {
		search: function (e) {
			e.preventDefault();
			e.stopPropagation();

			axios.post('/api/booking/search?api_token=' + this.user.api_token, {
				bookingId: this.bookingId
			})
			.then(response => {
				window.location.href = "/stjornbord/bokanir/" + response.data.id;
			})
			.catch(function (error) {
				console.log(error);
			});
		}
	},
};
</script>
ROTUES

Route::post('/booking/search', 'BookingController@search');

Route::get('/stjornbord/bokanir/{booking}', 'DashboardController@showBooking');
0 likes
14 replies
guybrush_threepwood's avatar

Hi @hjortur17

Have you tried logging the response to the console?

.then(response => {
    console.log(response.data);
    // window.location.href = "/stjornbord/bokanir/" + response.data.id;
})

I don't get what's the point of loading the booking with services if you're just going to redirect to /stjornbord/bokanir/id immediately after that (thus, losing the search result).

Shouldn't you load the services in your DashboardController@showBooking method instead?

1 like
hjortur17's avatar

How can I load the services in my showBooking method?

Can I use the $booking?

public function showBooking(Booking $booking)
	{
		return view('dashboard.showBooking', compact('booking'));
	}
guybrush_threepwood's avatar

You should be able to access them directly from the controller:

public function showBooking(Booking $booking)
	{
		foreach ($booking->service as $service) {
			// Do something
		}
	    
		return view('dashboard.showBooking', compact('booking'));
	}

Or directly from your blade template:

@foreach ($booking->service as $service)
    <p>This is service {{ $service->id }}</p>
@endforeach

You can also lazy load the relation on your controller in case you deem it necesarry (for example, if you want to change the default query order):

$booking->load(['services' => function ($query) {
    $query->orderBy('created_at', 'asc');
}]);
1 like
Snapey's avatar

I don't understand it?

You use the id to get the model with data so that you can get the id you already had and do a redirect?

hjortur17's avatar

@snapey - So what I'm trying to do is to have input on my website where you can look up booking id. If they exist, the page will redirect you to a edit page for that booking. But if no booking has that id, you typed in, it will display alert.

Snapey's avatar

so the booking id is different to the booking.id ?

Why then are you bothering to load services?

hjortur17's avatar

No, it's not different. But I change my search method to only see if the booking with that id you typed in exist and then redirect to edit page for that booking. And that's why I need to load services associated with that booking, so I can choose or remove a another service.

So this is my search method on the BookingController:

$booking = Booking::where('id', '=', $request->bookingId)->first();

return $booking;

And that's my search vue file:

search: function (e) {
			e.preventDefault();
			e.stopPropagation();

			axios.post('/api/booking/search?api_token=' + this.user.api_token, {
				bookingId: this.bookingId
			})
			.then(response => {
				if (response.data) {
					window.location.href = "/stjornbord/bokanir/" + response.data.id;
				} else {
					alert('Engin bókun með þetta númer!');
				}

			})
			.catch(function (error) {
				console.log(error);
			});
		}
Snapey's avatar
Snapey
Best Answer
Level 122

ok, thats not what you posted earlier, which did not make sense because you were loading services but not using them.

Your search now just trys the load the booking, and if it gets it then all is ok, it returns it and the redirect works?

But if the booking is invalid then you just return null (with 200 status code) and try to use it in a redirect.

What you should do is return an error.

$booking = Booking::findOrFail($request->bookingId);

return $booking;

Then you should get a 404 back if the booking does not exist and you can handle that in your axios code.

However, you might prefer to be more purposeful and return an actual status to the client of 'found' or 'not found'

hjortur17's avatar

@snapey - Hi, I'm having trouble getting Axios to display alert if I get 404 from the controller. Any idea?

if (response.status === 200) {
	window.location.href = "/stjornbord/bokanir/" + response.data.id;
} else if (response.status === 404) {
	alert('Engin bókun með þetta númer!');
}
Snapey's avatar

have you used network tools in the browser to check you actually get a 200/404 response ?

Are you sending the csrf token?

hjortur17's avatar

Yes, I'm sure that I'm sending the CSRF token.

When I console.log out the response.status, I get 200 when it's finds a booking but this message when I got 404: Error: Request failed with status code 404

Snapey's avatar

You need to handle the error in the catch block ?

search: function (e) {
			e.preventDefault();
			e.stopPropagation();

			axios.post('/api/booking/search?api_token=' + this.user.api_token, {
				bookingId: this.bookingId
			})
			.then(response => {
				window.location.href = "/stjornbord/bokanir/" + this.bookingId;
			})
			.catch(function (error) {
				alert('Engin bókun með þetta númer!');
			});
		}
1 like
hjortur17's avatar

That's true, but do you know if it's possible to load the services by using the variable? Because my route looks like this:

Route::get('/stjornbord/bokanir/{booking}', 'DashboardController@showBooking');

And this is my method:

public function showBooking(Booking $booking)
	{
		return view('dashboard.showBooking', compact('booking'));
	}

So I'm trying to loop through every service chosen with Vue but it doesn't recognize any when I try $booking->services

Snapey's avatar

Of course

	public function showBooking(Booking $booking)
	{
		$booking->load('services');

		return view('dashboard.showBooking', compact('booking'));
	}
1 like

Please or to participate in this conversation.