Laravel4: double post route - laravel

Sorry if can sound strange, but in the routes, on the post of my view I need to do two operations:
Route::post('booking', 'HomeController#booking');
Route::post('booking', function()
{
return Queue::marshal();
});
But of course doing this I get an error: Invalid data.
Yet for the post of the view 'booking' I need to call the method of the controller, and at the same time return Queue::marshal()
There is perhaps I can do this?
Thank you very much!
EDIT:
Here is the HomeController#booking method:
http://paste.laravel.com/19ej

If you define two routes with the same verb and url, the second one is never going to be fired.
Route::post('booking', 'HomeController#booking'); // Laravel will find this route first
Route::post('booking', function() // so this function will never be executed
{
return Queue::marshal();
});
I see that your HomeController#booking() is handling a form. Why can you just use another route for this?
Route::post('booking/create', 'HomeController#booking');
And then change your form action method to point to this route:
// this will render <form method="POST" action="http://yourdomain.com/booking/create"
{{ Form::open(array('action' => 'HomeController#booking')) }}
This way you don't have one route overlapping the other.
Some advice unrelated to the question. Taking a look at your controller, I have noticed that you do this when checking for errors:
if ( ! $errorCondition) {
// do stuff
} else {
// show errors
}
Your code will be a lot easier to read if you write it like this:
if ($errorCondition) {
// return error
}
// do stuff

Related

Same route, different page for authenticated user or not

I want to display either welcome.blade.php or login.blade.php with the same base url / (because the login is in the main page)
Is this a good convention to check it in the web.php:
Route::get('/'), function () {
if (auth()->check()) {
// return the welcome.blade.php view
} else {
// return the login.blade.php view
}
}
Or I should do this in a different place?
Separation of concern ! It means that whatever the module/method you write should be pure from side effects and has only one job.
web.php in routes directory serves all the routes file. So if you try to put the business logic here, it will still work but it will violate the standard of framework. All business logic either should go to controllers , helpers and all the authentication related stuff should go to middlewares. Therefor, we should handle this logic inside the controllers if it is specific to single route. In our case /. Otherwise if we have to handle generic authentication stuff, we should go into middleware.
Therefor, the flow would look something like this
User hit the route /
Through the web.php, it redirected to particular controller let say HomeController.
Inside the HomeController , you will put the same condition and render the view accordingly. i.e
if (auth()->check()) {
// return the welcome.blade.php view
} else {
// return the login.blade.php view
}
We can achieve the same thing in web.php but it will not be according to the framework standard. Further, If you have to do more stuff other than just rendering view, it will get more complicated in web.php.
I hope it will answer your question.
Thanks,

Laravel Livewire how to redirect before render

I want to redirect if Auth::user()->id is not equal to Ad->user_id
it does not work inside the mount or hydrate method.
$this->ad = Ad::where('id', $this->ad_id);
if ($this->ad->user_id != Auth::User()->id) {
return redirect()->route('dashboard');
}
You can redirect from mount() method. You can't redirect inside render as you would need to call return redirect('/') which would throw an error "render" method on [App\Http\Livewire\...] must return instance of [Illuminate\View\View]
function mount(){
if(condition fails){
return redirect()->to('someplace');
}
}
Livewire does not do backend redirects as far as I experienced, but rather uses JS to do them. So if you use the $this->redirect method, it will tell rendered component to perform the redirect. Some solutions I've seen on the web were in the render function, if you have an issue that results in a redirect being required, create an empty blade file with a simple div inside, and everywhere you need to redirect the user, set the render view as the blank one, and the FE will take the redirect. A pretty messy fix, but I did not see any better ones currently.
I tried everything but below-mentioned trick worked for me.
Rather than routing from the livewire component we can route from the livewire blade component by adding below code.
#php
$carts = \Cart::getContent();
if(count($carts) == 0)
{
$this->redirect('/shopping-cart/bag');
}
#endphp
Suggestions:
Don't use "return" while redirecting otherwise you might face some Front-end issues.
Don't use "route" while redirecting otherwise the code won't work.

How to pass variables from Controller to View without refreshing the Web Page in Laravel?

Whenever there is a call to Controller inside View, I want the Controller to return some variables to the View and do not refresh the View.
Already know:
return view("webpage" , compact('variable1', 'variable2') );
What I expect to achieve:
return compact('variable1', 'variable2');
This will not return the Webpage but only some of the variables.
Edit:
Thinking it from a complete different perspective, The question maybe rephrased as such
Is there a way to manipulate REQUEST variables of a web page from the controller? This way, i would be able to get new variables from the Controller without the web page being Refreshed.
With out much to work with, here is an example:
Ajax call:
$.ajax({
url: '/your/route/',
type: 'GET',
data: {getVariable: formInputValue},
})
.done(function (data) {
console.log(data);
})
.fail(function () {
console.log('Failed');
});
Controller Function:
public function getVariable(Request $request){
$resault = $request->getVariable;
return response()->json($results);
}
Update: as per comments on this answer try this and see if it works for you.
In your controller where you fetch records instead of using a ->get();
change it to paginate(5); this will return 5 records per page. and on your view at the bottom of your </table> add {{ $variable->links() }}

Serialize Laravel Query Builder

I would like to be able to construct a query using laravel, and serialize it into a url string.
This would allow me to create routes which would unserialize a query builder, run the query, and make a view which displays the database results.
For example, to implement a button which refreshes a list of posts made by kryo:
http://example.com/ajax/posts.php?name=kryo&order_by=created_at&order_type=desc
Posts.php would simply be a route which unserializes, validates, and runs the query in the url params, and provides the results to a view.
Perhaps this is not useful in general, but I would personally find it handy specifically for ajax requests. If anyone knows how to implement this as a laravel plugin of some nature, that would be fantastic.
I'll try to give you a basic idea:
In Laravel you have to create a route to make a request to a function/method, so at first you need to create a route which will be listening for the ajax request, for example:
Route::get('/ajax/posts', array('uses' => 'PostController#index', 'as' => 'showPosts'));
Now, create a link in the view which points to this route, to create a link you may try this:
$url = to_route('showPosts');
If you use something like this:
<a class='ajaxPost' href="{{ $url }}?name=kryo&order_by=created_at&order_type=desc">Get Posts</a>
It'll create a ink to that route. So, make sure you are able to pass that $url to your JavaScript or manually you can write the url using /ajax/posts?name=.... Once you done creating the link then you need to create your JavaScript handler for this link (maybe using click event) then handle the click event from your handler, make ajax request, if it's jQuery then it could be something like this:
$('.ajaxPost').on('clcik', function(e){
e.preventDefault();
var url = $(this).attar('href');
$.getJSON(url, function(response){
$.each(response, function(key, value){
// loop... you may use $(this) or value
});
});
});
In your PostController controller class, create the index method:
class PostController extends BaseController {
public function index()
{
$name = Input::get('name');
$order_by = Input::get('order_by');
$created_at = Input::get('created_at');
$order_type = Input::get('order_type');
$posts = Post::whereName($name)->orderBy($order_by, $order_type)->get();
if(Request::ajax()) {
return Response::json($posts);
}
else {
// return a view for non ajax
}
}
}
If you want to send a rendered view from the server side to your JavaScript handler as HTML then change the getJson to get and instead of return Response::json($posts); use
return View::make('viewname')->with('posts', $posts);
In this case make sure that, your view doesn't extends the master layout. This may not be what you need but it gives you the idea how you can implement it.

Laravel 4: if statement in blade layout works strange

Could someone explain me why I get blank screen with printed string "#extends('layouts.default')" if I request page normally (not ajax)?
#if(!Request::ajax())
#extends('layouts.default')
#section('content')
#endif
Test
#if(!Request::ajax())
#stop
#endif
I'm trying to solve problem with Ajax, I don't want to create 2 templates for each request type and also I do want to use blade templates, so using controller layouts doesn't work for me. How can I do it in blade template? I was looking at this Laravel: how to render only one section of a template?
By the way. If I request it with ajax it works like it should.
Yes #extends has to be on line 1.
And I found solution for PJAX. At the beginning I was not sure this could solve my problem but it did. Don't know why I was afraid to lose blade functionality if you actually can't lose it this way. If someone is using PJAX and needs to use one template with and without layout this could be your solution:
protected $layout = 'layouts.default';
public function index()
{
if(Request::header('X-PJAX'))
{
return $view = View::make('home.index')
->with('title', 'index');
}
else
{
$this->layout->title = 'index';
$this->layout->content = View::make('home.index');
}
}
Try moving #extends to line 1 and you will see the blade template will render properly.
As for solving the ajax problem, I think it's better if you move the logic back to your controller.
Example:
…
if ( Request::ajax() )
{
return Response::eloquent($books);
} else {
return View::make('book.index')->with('books', $books);
}
…
Take a look at this thread for more info: http://forums.laravel.io/viewtopic.php?id=2508
You can still run your condition short handed in the fist line like so
#extends((Request::ajax())?"layout1":"layout2")

Resources