Laravel:Call to a member function store() on null - php

I'm using Laravel to get the request file from postman, however it seems Laravel cannot identify the file I posted. Following is my code:
namespace App\Http\Controllers;
use App\Product;
use Illuminate\Http\Request;
class ProductImageController
{
public function update(Request $request, $id)
{
$path = $request->file('file')->store('images');
$product = Product::find($id);
$product->img_url = $path;
return $product->save() ?
response(["error_code" => 0, $product]) :
response(["error_code" => 1]);
}
}
Postman request

add this to your method and check if there is any errors and check if form-data is selected in postman, Be careful with explicit Content-Type header. Better - do not set it's value, the Postman is smart enough to fill this header for you. BUT, if you want to set the Content-Type: multipart/form-data - do not forget about boudary field.:
public function update(Request $request, $id)
{
$this->validate($request, [
'file' => 'required|file'
]);
...

I think you can try this:
if ($request->hasFile('file')) {
$product->img_url = $request->file('file')->store('images');
}
AND more info please follow this link
Hope this work for you !!!

try to:
-Change Put to Post in postman also in your ROUTE
-add this validator to your controller :
$validator = Validator::make($request->all(),[
'file' => 'file|required'
]);
if ($validator->fails()) {
return response()->json(['error' => $validator->errors()], 401);
}

Related

Laravel - Is it possible to validate a get wildcard Request with Illuminate\Foundation\Http\FormRequest;

I have a GET route with a wildcard day.
This day wildcard is a string like so: 20220507 (YYYYMMDD).
After validation the string I wish to make a proper response. Before sending the response I want to validate the string length and the format.
My question is, is it possible to validate the string with Illuminate\Foundation\Http\FormRequest ou Illuminate\Http\Request
make:request ? Or they only accepet Post Requests ?
Code:
php artisan make:request CalendarDayRequest
Example get route in web.php
Route::get('/calendar/{day}' , 'App\Http\Controllers\HomeController#calendar')->name('calendar');
Example Controller
use App\Http\Requests\CalendarDayRequest;
public function calendar ( CalendarDayRequest $request ) {
// Code
}
Or Example Controller 2
use Illuminate\Http\Request;
public function calendar ( Request $request ) {
$validated = $request->validate([
'day' => 'required',
]);
}
Both of them I got the error: infinite redirect loop, redirected it too many times.
Firstly, you can not validate route parameters inside Form Request
But, you can use regex for validating your route
Example:
Route::get('/calendar/{day}', 'App\Http\Controllers\HomeController#calendar')
->name('calendar')
->where('day', '/^[0-9]{4}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])$/');
If You still want to use validate() function or Form Request
$request->merge([
'day' => $day
]);
$this->validate($request, [
'day' => 'date_format:Ymd',
]);
Form Request Way - Override all() method
public function all($k = null){
$data = parent::all($k);
$data['day'] = $this->route('day');
return $data;
}
If Nothing Works, Try Following code
public function calendar(Request $request, $day){
$data = $request->all();
$data['day'] = $day;
$validator = Validator::make($data, [
'day' => 'required|date_format:Ymd',
]);
if($validator->fails()){
// Do Something abort(404);
}
}
Laravel 5 how to validate route parameters?
But I would suggest you to send it as request parameter if you want to use validate() function.
In Example 1:
You should overwrite this method in CalendarDayRequest:
protected function failedValidation(Validator $validator) {
throw (new ValidationException($validator))
->errorBag($this->errorBag)
->redirectTo($this->getRedirectUrl());
}
If client expects json, laravel will return a json field instead of redirection. You can completely change this behavior by changing this method or customizing render() method in App\Exceptions\Handler.
In Example 2:
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
public function calendar ( Request $request ) {
$validator = Validator::make($request->all(), ['day'=>'required']);
if ($validator->fails()) {
$errors = $validator->errors();
$messages = $validator->errors()->messages();
$messageBag = $validator->errors()->getMessageBag();
};
}
So you can use messages of validator for informing client.

"The GET method is not supported for this route. Supported methods: POST ."

I'm trying to add a new Post but whenever i submit i get the above error message.
This is Route:
Route::get('/p/create' , [App\Http\Controllers\PostsController::class, 'create']);
Route::post('/p' , [App\Http\Controllers\PostsController::class, 'store']);
and this is my controller:
{
public function create(){
return view('posts.create');
}
public function store(){
$data = request()->validate([
'caption'=>'required',
'image'=>'required|image',
]);
$imagePath =request('image')->store('uploads' ,'public');
// auth()->user()->posts()->create($data);
auth()->users()->posts()->create([
'caption' => $data['caption'],
'image' => $imagePath,
]);
//dd(request()->all() );
return redirect('/profile/' . auth()->user()->id);
}
}
Anyone faced the same problem?
Your problem is in your client side .
You should submit your form with post method not get.
for example this form send post method :
<form action="{{route('example_route')}}" method='post' >
//some html here
</form>
Try Modifying the store method to
public function store(Request $request){
$data = $request->validate([
'caption'=>'required',
'image'=>'required|image',
]);
//...

validation getting failed in Laravel API

In laravel controller validation getting failed, please help.
Repository: https://github.com/dhawlesudhir/basic_app.git
ProductController.php:
protected function validateRequest()
{
return request()->validate([
'name' => 'required|min:10|max:255',
'price' => 'required|integer|min:100',
'category_id' => 'required|exists:categories,id'
]);
}
public function store()
{
$data = $this->validateRequest();
$product = Product::create($data);
return new ProductResource($product);
}
api.php:
Route::apiResource('/products', ProductController::class);
Laravel throwing validation because you haven't set json in postman.
I can see currently you have set Text.
Set type to json like in screenshot
Otherwise Laravel receives empty array from request()->all()
Also make sure to set header Accept:application/json .

Insert array of arrays in Lumen with Eloquent ORM

The POST request I'm sending looks like this:
{ "array1":
[
{"title":"my blogADD","description":"myblogdescriptionADD","status":1},
{"title":"my blogUPDATEDADD","description":"myblogdescriptionUPDATEDADD","status":1},
{"title":"my blog33ADD","description":"myblogdescription33ADD","status":1}
]
}
Its JSON format, headers have been set.
The controller code which gets the request looks like this:
public function create(Request $request){
$this->validate($request, [
'array1' => 'present|array',
'array1.*.title' => 'required',
'array1.*.description' => 'required'
]);
$data = $request->getContent();
$data = json_decode($data, true);
//dd($data);
Article::insert($data);
}
Now, I've looked into multiple questions and answers on SO on this problem, and the findings are somehow contradictory.
Model::insert() shall be able to insert multiple rows in ONE call.
However, as you can see, this hasn't worked for me so far.
Model::create() is only able to create one new row, but I found solutions which use loops to iterate over the arrays. I would very very much like to avoid such a solution, unless someone can FOR CERTAIN tell me that there is no other, simple solution. Because I very much believe that there must be one.
When I input the json_decoded ARRAY then I get the response that an Array to String conversion is hindering the process.
When I input the mere JSON-String, then I get the error:
"Argument 1 passed to Illuminate\Database\Query\Builder::insert() must be of the type array, string given, called in E:\LumenTut\firstTut\vendor\illuminate\database\Eloquent\Builder.php on line 1350"
Well, here are two links to SO posts which, in my opinion, basically dealt with the same problem. But somehow it seems they could solve it and I can't, so I wonder what I am missing:
How to insert a multidimensional array in a database using laravel
laravel 5.6 bulk inserting json data
For completeness, here is the full Code of ArticleController.php:
EDIT:
<?php
namespace App\Http\Controllers;
//use Validator;
use App\Article;
use Illuminate\Http\Request;
class ArticleController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
//
}
//
public function showAllArticles(){
return response()->json(Article::get(['title', 'description', 'status'])); // ::get([]) spezifiziert die zu referenzierenden Attribute
// ::all() referenziert alle Attribute einer Tabelle/Relation
}
public function showOneArticle($id){
return response()->json(Article::find($id));
}
public function create(Request $request){
$this->validate($request, [
'array1' => 'present|array',
'array1.*.title' => 'required',
'array1.*.description' => 'required'
]);
$data = $request->getContent();
//$data = json_decode($data, true);
//dd($data);
Article::insert($data);
}
public function update($id, Request $request){
$this->validate($request, [
'title' => 'required',
'description' => 'required'
]);
$article = Article::findOrFail($id);
$article->update($request->all());
return response()->json($article, 200);
}
public function delete($id, Request $request){
Article::findOrFail($id)->delete();
return response('Deleted Successfully', 200);
}
public function resetRecords(Request $request){
Article::where('id', '>', 2)->delete();
}
}
From the looks of it, it feels like you are trying to push array1 directly in your table, whereas you need to push the content of it so maybe try like this, in your controller code:
$requestData = $request->all();//this will give you an array with key array1
$data = $requestData['array1'];//this will give you data you want to insert
Article::insert($data);
Based on the error. You are not passing an array. You can change the $data with
$data = $request->all();
$request->all() returns the data from the post in array.
You can rewrite your create method with the following.
public function create(Request $request){
$request->validate([
'array1' => 'present|array',
'array1.*.title' => 'required',
'array1.*.description' => 'required'
]);
$data = $request->all();
Article::insert($data['array1']);
}

Laravel test response with The given data was invalid

I'm doing unit test with laravel, so I called controller function and I get like a respnse an array
I have been response with this
return back()->with('success', 'Lots was generated')
and
return $this->lots_available;
The test give me as response this:
There was 1 error:
Tests\Feature\LotTest::test_lots
Illuminate\Validation\ValidationException: The given data was invalid.
I don't understand the reazon to this response, I'm beginning with the test
This is my function test
public function test_lots()
{
$this->withoutExceptionHandling();
$product = factory(Product::class)->create([
'size' => 20
]);
$lots = factory(Lot::class, 10)->create([
'product_id' => $product->id,
]);
$admin = factory(User::class)->create([
'role_id' => 3
]);
$client_request = 500;
$this->actingAs($admin)
->post(route('lots.distribution'), [$product, $client_request])
->assertStatus(200);
}
And this my called method
public function distribute(ProductRequest $product, $client_order)
{
$this->lots = $product->lots;
$this->client_order = $client_order;
$this->getLotAvailable();
return $this->lots_available;
}
Assuming your route is something like Route::post('/distribute/{product}/{client_order}')
route('lots.distribution') needs the parameters inside the function call
route('lots.distribution', [$product, $client_request])
Then you need to send the data that passes your rules in ProductRequest otherwise you will get a validation error. If you try a dd(session('errors')) after the post, you will probably see errors about missing fields.
->post(
route('lots.distribution', [$product, $client_request]),
['title => 'unique_title', 'sap_id' => 'unique_id']
)
Finally in your method, I'm assuming that the request ProductRequest is different than the Model Product:
public function distribute(ProductRequest $request, Product $product, $client_order)
Put the response in a variable and use dd() to print it.
You will find it on the messages method.
Worked for me.
dd($response);

Categories