How I can make route API in Laravel with parameter - laravel

my route:
Route::get('page/{key_id_fk}', 'PagesApiController#show');
my function:
public function show($key_id_fk)
{
$sub=DefintionDetails::find($key_id_fk);
// $main=Definition::where([['type','=',1],['available','=',1],['id_definition','=',$sub->id_def]])->get();
return response()->json($sub , 200);
}
on post man route is page?key_id_fk=1 give error 404 not found key in data base but didn't read.

You should be accessing page/1 rather than page?key_id_fk=1 as you are not using parameter queries in your request url.
Your route format is page/$key_id_fk.

In the route file:
Route::get('page/{key_id_fk}', 'PagesApiController#show');
In the controller:
public function show($key_id_fk){
$sub = DefintionDetails::find($key_id_fk);
if($sub){
return response()->json(['success' => true, 'sub' => $sub]);
} else {
return response()->json(['success' => false, 'error_message' => 'No data found!']);
}
}
Your postman route:
http://example.com/page/1

You are setting key_id_fk as http://example.com/page/1 in route and passing parameter as http://example.com/page?key_id_fk=1 difference is first one is URL route data and second is GET parameter data to get data from URL route you have this public function show($key_id_fk) and to get data from GET parameter public function show(Request $request) and $request->key_id_fk.
so change URL to this http://example.com/page/1 format
or
change getting method in the controller to public function show(Request $request) and $request->key_id_fk

Related

Laravel API routes and Controller variable

I'm a new user of Laravel, and i'm a bit confused with Laravel route API and the name of variable in the controller.
Here an example to explain :
An API route
Route::middleware('auth:sanctum')->group( function () {
Route::resource('cepage', CepageController::class);
});
For a PUT or PATCH, i have this function in the CepageController :
public function update(Request $request, Cepage $cepage)
{
$input = $request->all();
$validator = Validator::make($input, [
'libelle' => 'required',
'abrege' => 'required'
]);
if($validator->fails()){
return $this->sendError($validator->errors());
}
$cepage->libelle = $input['libelle'];
$cepage->abrege = $input['abrege'];
$cepage->save();
return $this->sendResponse(new CepageResource($cepage), 'Cépage mis à jour');
}
If you see my route name "cepage" have the same name of the $cepage variable of the function declaration in the controller, Laravel update the record in the database.
If they are no identical, Laravel create a new record in the database.
Why they need to be exactly the same ?
I think i miss something in the documenation of Laravel.
Thanks for your explanations.
It needs to be the same, for laravel to know what object does he needs to create for us.
Route::resource does a few routes for you, with the base url give into it (https://laravel.com/docs/8.x/controllers#actions-handled-by-resource-controller)
So once you have defined Route::resource('cepage', CepageController::class)
You will have the following routes defined:
Verb URI Action Route Name
GET /cepage CepageController#index cepage.index
GET /cepage/create CepageController#create cepage.create
POST /cepage CepageController#store cepage.store
GET /cepage/{cepage_id} CepageController#show cepage.show
GET /cepage/{cepage_id}/edit CepageController#edit cepage.edit
PUT/PATCH /cepage/{cepage_id} CepageController#update cepage.update
DELETE /cepage/{cepage_id} CepageController#destroy cepage.destroy
And in the controller you need to follow the naming, because in the url you have only ids of the object. But if you follow the naming, laravel will fetch the object for you by its id. See:
public function update(Request $request, $cepage_id)
{
$cepage = Cepage::find($cepage_id);
//here you have to fetch the object for yourself to access it
}
public function update(Request $request, Cepage $cepage)
{
//here you can already access $cepage variable
}

Redirect from controller to named route with data in laravel

I'm gonna try to explain my problem:
I have a named route called 'form.index' where I show a html form.
In FormController I retrieve all form data.
After do some stuff with these data, I want to redirect to another named route 'form.matches' with some items collection.
URLS
form.index -> websiteexample/form
form.matches -> websiteexample/matches
FormController
public function match(FormularioRequest $request)
{
// Some stuffs
$list = /*Collection*/;
return redirect()->route('form.matches')->with(compact('list'));
}
public function matches()
{
// How to retrieve $list var here?
return view('form.views.matches')->with(compact('list'));
}
The problem:
When the redirects of match function occurs, I get an error "Undefined variable: list' in matches funcion.
public function match(Request $request)
{
// Operations
$list = //Data Collection;
return redirect()->route('form.matches')->with('list',$list);
}
In view
#if(Session::has('list'))
<div>
{!!Session::get('list')!!}
</div>
#endif
You can use Redirect::route() to redirect to a named route and pass an array of parameters as the second argument
Redirect::route('route.name',array('param1' => $param1,'param2' => $param2));
Hope this helps you.

Laravel.54 pass data to action controller

I need to get 'mp3' value in controller !
( to check posts from mp3s type )
my post types :
video, album , mp3
(web.php)
Route::group(array('prefix' => 'mp3s'), function($pt) {
Route::get("/", "PostController#archivePosts");
Route::get("mp3/{slug}", "PostController#singlePost");
});
Route::group(array('prefix' => 'albums'), function($pt) {
Route::get("/", "PostController#archivePosts");
Route::get("album/{slug}", "PostController#singlePost");
});
Route::group(array('prefix' => 'videos'), function($pt) {
Route::get("/", "PostController#archivePosts");
Route::get("video/{slug}", "PostController#singlePost");
});
#danial dezfooli
To Get Prefix value you can inject Request Dependency inside controller's method as below.
public function index(\Illuminate\Http\Request $request){
dd($request->route()->getPrefix());
}
or you can do in another way also
public function index(){
dd($this->getRouter()->getCurrentRoute()->getPrefix());
}
For more reference you can refer : Laravel 5 get route prefix in controller method
Route::get("mp3/{slug}", "PostController#singlePost");
In PostController, you can get it like
public function singlePost($slug) {
dd($slug)// to check slug value
}

How to change response in Laravel?

I have RESTful service that is available by endpoints.
For example, I request api/main and get JSON data from server.
For response I use:
return response()->json(["categories" => $categories]);
How to control format of response passing parameter in URL?
As sample I need this: api/main?format=json|html that it will work for each response in controllers.
One option would be to use Middleware for this. The below example assumes that you'll always be returning view('...', [/* some data */]) i.e. a view with data.
When the "format" should be json, the below will return the data array passed to the view instead of the compiled view itself. You would then just apply this middleware to the routes that can have json and html returned.
public function handle($request, Closure $next)
{
$response = $next($request);
if ($request->input('format') === 'json') {
$response->setContent(
$response->getOriginalContent()->getData()
);
}
return $response;
}
You can use for this Response macros. For example in AppServiceProvider inside boot method you can add:
\Response::macro('custom', function($view, $data) {
if (\Request::input('format') == 'json') {
return response()->json($data);
}
return view($view, $data);
});
and in your controller you can use now:
$data = [
'key' => 'value',
];
return response()->custom('your.view', $data);
If you run now for example GET /categories you will get normal HTML page, but if you run GET /categories?format=json you will get Json response. However depending on your needs you might need to customize it much more to handle for example also redirects.
With your format query parameter example the controller code would look something like this:
public function main(Request $request)
{
$data = [
'categories' => /* ... */
];
if ($request->input('format') === 'json') {
return response()->json(data);
}
return view('main', $data);
}
Alternatively you could simply check if the incoming request is an AJAX call via $request->input('format') === 'json' with $request->ajax()

Passing route parameter to controller Laravel 5

I'm trying to pass a route parameter to controller, but I get this error : Argument 2 passed to App\Http\Controllers\JurnalController::store() must be an instance of App\Http\Requests\JurnalRequest, none given
Below are the codes ..
Route :
Route::get('/edisi/{id}', 'JurnalController#store');
Controller :
public function store($id, JurnalRequest $request) {
$input = $request->all();
//Input PDF
if ($request->hasFile('file')) {
$input['file'] = $this->uploadPDF($request);
}
$jurnal = Edisi::findOrFail($id)->jurnal()->create($input);
return redirect('jurnal');
}
So my question is how to pass the route parameter properly ? Thank you
new routes :
Route::get('/', function () {
return view('pages/home');
});
Route::group(['middleware' => ['web']], function () {
Route::get('edisi', 'EdisiController#index');
Route::get('edisi/create', 'EdisiController#create');
Route::get('edisi/{edisi}', 'EdisiController#show');
Route::post('edisi', 'EdisiController#store');
Route::get('edisi/{edisi]', 'EdisiController#edit');
Route::patch('edisi/{edisi}', 'EdisiController#update');
Route::delete('edisi/{edisi}', 'EdisiController#destroy');
});
Route::get('/edisi/{id}', 'JurnalController#storejurnal');
Route::group(['middleware' => ['web']], function () {
Route::get('jurnal', 'JurnalController#index');
Route::get('jurnal/create', 'JurnalController#create');
Route::get('jurnal/{jurnal}', 'JurnalController#show');
Route::post('jurnal', 'JurnalController#storejurnal');
Route::get('jurnal/{jurnal}/edit', 'JurnalController#edit');
Route::patch('jurnal/{jurnal}', 'JurnalController#update');
Route::delete('jurnal/{jurnal}', 'JurnalController#destroy');
});
new storejurnal method :
public function storejurnal(JurnalRequest $request, $id) {
$input = $request->all();
//Input PDF
if ($request->hasFile('file')) {
$input['file'] = $this->uploadPDF($request);
}
//Insert data jurnal
$jurnal = Edisi::findOrFail($id)->jurnal()->create($input);
return redirect('jurnal');
}
When you are using resource controller, the store method does not accept any other argument except the Request instance. Try changing the method name or remove the second argument. store() method be default accepts post requests not get requests. Either put your route on top of the resource controller or change the method name.
Route::get('/edisi/{id}', 'JurnalController#store');
Route::resource('jurnals', 'JurnalController');
I hope this helps.
The correct format is:
public function store(JurnalRequest $request, $id) {
// your code
}
If you receive an argument such as Missing argument 2 as suggested in your comments, it means that either you aren't generating the routes correctly, or the url doesn't include the id segment.

Resources