I have RESTful API built on Laravel.
Now I'm passing parameter like
http://www.compute.com/api/GetAPI/1/1
but I want to pass parameter like
http://www.compute.com/api/GetAPI?id=1&page_no=1
Is there a way to change Laravel routes/functions to support this?
you can use link_to_route() and link_to_action() methods too.
(source)
link_to_route take three parameters (name, title and parameters). you can use it like following:
link_to_route('api.GetAPI', 'get api', [
'page_no' => $page_no,
'id' => $id
]);
If you want to use an action, link_to_action() is very similar but it uses action name instead of route.
link_to_action('ApiController#getApi', 'get api', [
'page_no' => $page_no,
'id' => $id
]);
href text
with these methods anything after the expected number of parameters is exceeded, the remaining arguments will be added as a query string.
Or you can use traditional concatination like following:
create a route in routes.php
Route::get('api/GetAPI', [
'as' => 'get_api', 'uses' => 'ApiController#getApi'
]);
while using it append query string like this. you can use route method to get url for required method in controller. I prefer action method.
$url = action('ApiController#getApi'). '?id=1&page_no=1';
and in your controller access these variables by following methods.
public function getApi(Request $request) {
if($request->has('page_no')){
$page = $request->input('page_no');
}
// ...your stuff
}
Or by Input Class
public function getApi() {
if(Input::get('page_no')){
$page = Input::get('page_no');
}
// ...your stuff
}
Yes you can use those parameters, then in your controllers you can get their values using the Request object.
public function index(Request $request) {
if($request->has('page_no')){
$page = $request->input('page_no');
}
// ...
}
Related
I need to make custom request and use its rules. Here's what I have:
public function rules()
{
return [
'name' => 'required|min:2',
'email' => 'required|email|unique:users,email,' . $id,
'password' => 'nullable|min:4'
];
}
The problem is that I can't get $id from url (example.com/users/20), I've tried this as some forums advised:
$this->id
$this->route('id')
$this->input('id')
But all of this returns null, how can I get id from url?
When you are using resources, the route parameter will be named as the singular version of the resource name. Try this.
$this->route('user');
Bonus points
This sound like you are going down the path of doing something similar to this.
User::findOrFail($this->route('user'));
In the context of controllers this is an anti pattern, as Laravels container automatic can resolve these. This is called model binding, which will both handle the 404 case and fetching it from the database.
public function update(Request $request, User $user) {
}
This is my code using to send an email
Route::post('/mail/send', [
'EmailController#send',
]);
in EmailController this is the send action
public function send(Request $request)
{
$data = $request->all();
$data['email'] = Input::get('email');
$data['name'] = Input::get('name');
$obj = new \stdClass();
$obj->attr = 'Hello';
Mail::to("dev#mail.com")->send(new WelcomeEmail($obj));
}
getting a error as Function () does not exist
In your route/web.php file
Change it to
Route::post('/mail/send', 'EmailController#send');
Refer to the documentation to see the possible options to define routes:
https://laravel.com/docs/5.6/routing
Route's action method can be defined using a array, but not simply wrap controller#action in an array, you should assign it to array's key 'uses'.
In your example, it should be like this:
Route::post('/mail/send', [
'uses' => 'EmailController#send',
//'middleware' => .... assign a middleware to this route, if needed
]);
the array form usually is used when we want to specify more specification about the route like use a specific middleware and pass middleware parameters.
if you just want to define route's processing method you can simply use controller#action as Route::post's second parameter:
Route::post('/mail/send','EmailController#send');
In your route ...
Route::post('/mail/send','EmailController#send')->name('send_email');
Inside of your HTML form add below code...
<form action="{{route('send_email')}}" method="post">
...
{{csrf_field()}}
I am returning an API response inside a Categories controller in Laravel 5.5 like this...
public function get(Request $request) {
$categories = Category::all();
return Response::json(array(
'error' => false,
'categories_data' => $categories,
));
}
Now I am trying to also have the option to return a specific category, how can I do this as I am already using the get request in this controller?
Do I need to create a new route or can I modify this one to return a specific category only if an ID is supplied, if not then it returns all?
Better case is to create a new route, but you can also change the current one to retrieve all models if the parameter is not supplied. You first gotta choose which approach you will be using. For splitting it into multiple calls you can see Resource controllers and for using one method you can follow Optional Route Parameters
It will be much cleaner if you will create another route. For example
/categories --> That you have
/categories/{id} -> this you need to create
And then add method at same controller
public function show($id) {
$categories = Category::find($id);
return Response::json(array(
'error' => false,
'categories_data' => $categories,
));
}
But if you still want to do it at one route you can try something like this:
/categories -> will list all categories
/categories?id=2 -> will give you category of ID 2
Try this:
public function get(Request $request) {
$id = $request->get('id');
$categories = $id ? Category::find($id) : Category::all();
return Response::json(array(
'error' => false,
'categories_data' => $categories,
));
}
Let's say I have a function in my controller which retrieves users looking something like this:
public function index($category) {
// retrieve users depending on category or all
}
Now is there a way to make named routes to include the function parameter like so:
Route::get('passengers', 'Controller#index(1)')->name('passengers');
Route::get('attendees', 'Controller#index(2)')->name('attendees');
This way they can all use the same function
No you can not pass a parameter the action name, and there is a problem in you routing logic :
Route::get('/{categoryName}', 'Controller#index')->name('index');
And in the controller you will for example get the category by name like this :
public function index($categoryName) {
$category = Category::where('name', $categoryName)->first();
// use $ category as you please ;)
}
In the blade :
route('index', ['categoryName' => $category->name])
If the named route defines parameters, you may pass the parameters as the second argument to the route function. The given parameters will automatically be inserted into the URL in their correct positions
https://laravel.com/docs/5.5/routing#named-routes
So, use route() helper like this:
route('passengers', ['category' => 1])
Then you need to add {category} to the route. Also, it's really better to use show() instead of index() here. So, your route will look like this:
Route::get('passengers/{category}', ['as' => 'passengers', 'uses' => 'Controller#show']);
Yes, you can define the param in the url like so:
Route::get('passengers/{yourParam}', 'Controller#index')->name('passengers');
View in docs
Route::get( '{category}', [ 'as' => 'users', 'uses' => 'Controller#index' ]);
Remember to add this route at the end of your routes file in order to not to collide with any other route.
Now in your controller
use Illuminate\Http\Request;
public function index(Request $request)
{
$category = $request->query('category');
// $category will be passengers, attendees, etc
}
Your routes will be
/passengers can be accessed as route('users', ['category' => 'passengers'])
/attendees can be accessed as `route('users', ['category' => 'attendees'])
Is there a built-in way to do something like this?
Let's say I have a search-page that has a few parameters in the URL:
example.com/search?term=foo&type=user
A link on that page would redirect to an URL where type is link. I'm looking for a method to do this without manually constructing the URL.
Edit:
I could build the URL manually like so:
$qs = http_build_query(array(
'term' => Input::get('term'),
'type' => Input::get('type')
));
$url = URL::to('search?'.$qs);
However, what I wanted to know is if there is a nicer, built-in way of doing this in Laravel, because the code gets messier when I want to change one of those values.
Giving the URL generator a second argument ($parameters) adds them to the URL as segments, not in the query string.
You can use the URL Generator to accomplish this. Assuming that search is a named route:
$queryToAdd = array('type' => 'user');
$currentQuery = Input::query();
// Merge our new query parameters into the current query string
$query = array_merge($queryToAdd, $currentQuery);
// Redirect to our route with the new query string
return Redirect::route('search', $query);
Laravel will take the positional parameters out of the passed array (which doesn't seem to apply to this scenario), and append the rest as a query string to the generated URL.
See: URLGenerator::route(),
URLGenerator::replaceRouteParameters()
URLGenerator::getRouteQueryString()
I prefer native PHP array merging to override some parameters:
['type' => 'link'] + \Request::all()
To add or override the type parameter and remove another the term:
['type' => 'link'] + \Request::except('term')
Usage when generating routes:
route('movie::category.show', ['type' => 'link'] + \Request::all())
You can do it with Laravel's URLGenerator
URL::route('search', array(
'term' => Input::get('term'),
'link' => Input::get('type')
));
Edit: be sure to name the route in your routes.php file:
Route::get('search', array('as' => 'search'));
That will work even if you're using a Route::controller()
From Laravel documentation:
if your route has parameters, you may pass them as the second argument
to the route method.
In this case, for return an URI like example.com/search?term=foo&type=user, you can use redirect function like this:
return redirect()->route('search', ['term' => 'foo', 'type' => 'user']);
Yes, there is a built in way. You can do your manipulation in Middleware.
The $request passed to the handle method of all middleware has a query property. As an InputBag, it comes with a few methods; Namely, for your intentions: ->set().
Pretty self explanatory, but here's an example:
public function handle(Request $request, Closure $next)
{
$request->query->set('term','new-value');
// now you pass the request (with the manipulated query) down the pipeline.
return $next($request);
}
The Input component should also contain query parameters.
i.e Input::get('foo');