Laravel if statement for request object - laravel

Currently building out an API. I am working on an update function with excepts the incoming request. so: api.dev.com/?api_key=asdf&storeid=2 etc
now in the backend i am accepting the Request and then i am trying to write some logic to check if the request includes storeid then update that entry etc.
But when i am writing my logic and i do
if(isset($request->storeid))
$store->id = $request->storeid;
If I do not include storeid in my put request then i get:
Call to a member function parameter() on a non-object
Because it is not present. Am I approaching writing this logic the wrong way?
I want to leave it up to the users to update the records they want. So they should not have to include all the variables in the request. Just those that need to be updated.
Citti

Do this instead:
if($request->has('storeid')) {
...

The error "Call to a member function parameter() on a non-object" is not because you are not including the "storeid" input, but because you are not calling an instance of the Store object.
Maybe if you do something like:
if(isset($request->storeid))
$store = Store::findOrFail($request->storeid)

Related

Laravel routing: is there a syntax to pass a fixed parameter to the handler function?

I am using Laravel 8 and currently I have the following route:
Route::match(['get'], '/{action}', '\App\Http\MyController#handleRequest');
In the MyController class I have a handlerRequest function which takes two parameters
public function handleRequest(Request $request, string $action)
{
// Generic request handling code for every action, both GET and POST
// This code is fairly long and I don't want it to be duplicated
}
This all works well until I want to add another route for a specific request:
Route::match(['post'], '/message-sent', '\App\Http\MyController#handleRequest');
In this case only the POST method is allowed on the specific action message-sent, however it does not work using the above configuration as Laravel does not pass "message-sent" as $action to the handleRequest function.
The error message is
Too few arguments to function App\Http\MyController::handleRequest(), 1 passed in /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php on line 48 and exactly 2 expected
What I want is the action "message-sent" is passed into the generic handler function as parameter but at the same time achieving the "special post-only setting" for this specific route.
I tried
Route::match(['post'], '/{message-sent}', '\App\Http\MyController#handleRequest');
as well without success.
After searching through the Laravel source code, I think I found the solution
Route::match(['post'], '/message-sent', '\App\Http\MyController#handleRequest')->defaults('action', 'message-sent');
would achieve the effect of sending a fixed parameter $action="message-sent" to the handler function.

getting query parameters from URL in laravel 7.1

Just as a learning exercise, I'm creating a REST API in Laravel 7.1. I'm having trouble figuring out how to parse the query string parameters in route methods. I've read over the documentation here, and it shows how to add parameters into the path:
Route::get('user/{id}', function ($id) {
return 'User '.$id;
});
However I don't see where you can get query parameters from the request URL. In my toy code, I want to add a route to add a new car to inventory:
Route::post('/inventory/add/{make}/{model}/{year}', function ($make, $model, $year) {
return \App\Inventory::create($model, $color, $trim, $accessories);
});
I want to specify parameters such as color, trim, and accessories through the query string, like so:
http://example.com/inventory/add/ford/focus/2020?color=red&trim=sport&accessories=chrome-wheels
How do I get the query parameters out of the Route::post method?
Edit I suppose this architecture may not be the optimal way of adding this extra information, but since I am trying to learn laravel, I am using it as an example. I am interested in learning how to get the query parameters moreso than how to improve the architecture of this learning example.
In Route::post you don't need set the parameters in route. Just use:
Route::post("your-route", "YourControllerController#doSomeThing");
So, in app/Http/Controllers/YourControllerController.php file:
class YourControllerController extends Controller {
public function doSomeThing(Request $request)
{
echo $request->input('param1');
echo $request->input('param2');
echo $request->input('param3');
}
You just need to inject the request instance into your handler (whatever a closure or controller method) and then ask for your parameters.
$color = $request->query('color', 'default-color');
//And so on...
https://laravel.com/docs/7.x/requests#retrieving-input

API request with multiple body inputs

I am new to laravel this is how I make an API with one single body item
$shops_categories=ShopsCategories::all()->where('title',$request->title);
how to request more than an item in the body for example title , email , password ?
Eloquent allows you to chain as many where as required. So you are able to do
$shops_categories = ShopsCategories::where('title',$request->title)->where('email',$request->email)->where('password',$request->email)->get();
You can do it like so:
$cats = ShopsCategories::query()->where(['title' => $title, 'email'=>$email, 'name'=>$name]);
i guess you are performing query operation in controller itself which is not recommended,please create an instance for the model and make a function call to model and in the model you can return like
return $this::where('id','=',$id)->get()
and also please try to avoid using text/string in where condition instead use id's or unique values
You can also convert request to array using all()
//$request->all() is same as ['title'=> 'my title', ...]
$shops_categories=ShopsCategories::where($request->all())->get();

Laravel - route model binding with request headers

I am wondering is it possible to do something similar to route model binding, but with request headers. I have a query that I check on my api endpoints, that looks like this:
User::where('telephone', $request->header('x-user'))->firstOrFail();
Is it possible to somehow avoid repeating this query in every method in controllers, but to apply it to routes, so that I could just get the user object just like in a route model binding with type hinting in a function, for every route that in an api routes folder:
public function userTransactions(User $user)
{
//
}
Create a middleware and assign it to the desired routes.
Option 1
In your middleware do:
$user = User::where('telephone', $request->header('x-user'))->firstOrFail();
request()->merge(['user_model' => $user]);
You can then request()->get('user_model') anywhere in your controller
Option 2
Start by creating a global scope class that conforms to your query. Here you'd get the header value and use that in the scope.
https://laravel.com/docs/5.5/eloquent#global-scopes
Next in the middleware, add the scope to the model using addGlobalScope
User::addGlobalScope(new HeaderScope())
Now all queries for User will have a where clause with your header value.
You can subsequently remove the scope or ignore global scopes if needed.

How to include an association with a user

I need to return a json object to my view. I see my subscriptions in tinker:
\App\User::find(1)->with('subscriptions')->where('id', 1)->get();
In my view, I get my user data but the subscriptions array is emply (length: 0)
Issue one, why I could not just \App\User::find(1)->with('subscriptions')->get() This returns all users in my database.
How can I return, as json, the current user with subscriptions? The long way is to make two api calls.
Im using Cashier for the subscriptions
Try to check the query log by running
\DB::enableQueryLog();
$data = \App\User::with('subscriptions')->find(1);
$query = \DB::getQueryLog();
dd($query);
It will show you what queries running behind the seens.
then for the json format try to decode into json and then pass to view.
$json_format = json_encode($data);
return view('user.index')->withJsonFormat($json_format);
Don't know why you want to pass the data with json format. but if you want to pass this into javascript, jquery or angular please create saperate API and call with AJAX.
The correct query is:
App\User::with('subscriptions')->find(1)
It will return User object with this user's subscriptions.

Resources