How to change response in Laravel? - 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()

Related

How to use parameter from function to create an URL? Laravel Routing

I'm sending an URL hashed and when i get it i have to show a view on Laravel, so i have those functions on the controller and also some routes:
This are my routes:
Route::post('/sendLink', 'Payment\PaymentController#getPaymentLink');
Route::get('/payment?hash={link}', 'Payment\PaymentController#show');
And this are the functions i have on my controller:
public function getPaymentLink (Request $request){
$budgetId = $request['url.com/payment/payment?hash'];
$link = Crypt::decryptString($budgetId);
Log::debug($link);
//here to the show view i wanna send the link with the id hashed, thats why i dont call show($link)
$view = $this->show($budgetId);
}
public function show($link) {
$config = [
'base_uri' => config('payment.base_uri'), ];
$client = new Client($config);
$banking_entity = $client->get('url')->getBody()->getContents();
$array = json_decode($banking_entity, true);
return view('payment.payment-data')->with('banking_entity', $array);
}
And this is getting a "Page not found" message error.
What i want to to is that when i the client clicks on the link i send him that has this format "url.com/payment/payment?hash=fjadshkfjahsdkfhasdkjha", trigger the getPaymentLink function so i can get de decrypt from that hash and also show him the view .
there is no need to ?hash={link} in get route
it's query params and it will received with $request
like:
$request->hash
// or
$request->get('hash')
You need to define route like this:
Route::get('/payment/{hash}', 'Payment\PaymentController#show');
You can now simply use it in your Controller method like below:
<?php
public function getPaymentLink (Request $request,$hash){
$budgetId = $hash;
// further code goes here
}

dd() not working in vue-laravel project axios call.Is it possible to use dump in axios call?

I am using vue with laravel.but my save function not working. So I tried to dump and die the request object but I can't see the request object in the preview. it is blank.
protected function save()
{
$request = Request::all();
dd($request);
$suggestion = new Suggestion();
$suggestion->connection_id = $request['connection_id'];
$suggestion->company_id = $request['company_id'];
$suggestion->module = $request['module'];
$suggestion->description = $request['image'];
$suggestion->save();
return 'success';
}
the axios call is
axios.post('suggestion/save', this.post).then(response => {
this.$swal({
title: 'Success',
text: response.data.message,
type: 'success',
confirmButtonText: 'OK',
});
this.$router.push('/suggestion-list');
})
There are multiple Request classes in Laravel, One thing you can try is the following,
public function controllerFunction()
{
dd(request()->all());
$suggestion = new Suggestion();
$suggestion->connection_id = $request['connection_id'];
$suggestion->company_id = $request['company_id'];
$suggestion->module = $request['module'];
$suggestion->description = $request['description'];
$suggestion->save();
return 'success';
}
So irrespective of your class, the request() function will bring up the appropriate object.
If you get to dump the request then you can confirm that the request is hitting the appropriate controller function, otherwise, the request is going somewhere else. check the network tab in chrome for more details.
Also, make sure you have the appropriate Request class in the use statements.
The correct Request class usage is like following
use Illuminate\Http\Request;
Add request to your function
also add 'use Illuminate\Http\Request'
use Illuminate\Http\Request
public function myFunction(Request $request)
{
dd($request->all());
...
}
hey you can use print() or print_r() to check result
and make sure your this.post has data or not

How I can make route API in Laravel with parameter

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

PUT in laravel API

I'm studying api rest with laravel, I was able to implement all methods except PUT. Although the routes and controllers are correctly configured a response to a request using the PUT method is "laravel put Sorry, the page you are looking for could not be found.", As now image.
here is the method code in the controller in app/Http/Controllers/LivroController.php:
public function store(Request $request) {
$livro = $request->isMethod('put') ? Livro::findOrFail($request->livro_id) : new Livro;
$livro->id = $request->input('livro_id');
$livro->nome = $request->input('nome');
$livro->descricao = $request->input('descricao');
$livro->user_id = 1; //$request->user()->id;
if($livro->save()) {
return new LivroResource($livro);
}}
here is the route code in /routes/api.php:
Route::put('livro', 'LivroController#store');
change your postman method to POST and then add new parameter in your Body :
"_method" : PUT
This is because HTML forms do not support PUT, PATCH or DELETE actions. So, when defining PUT, PATCH or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form
If you want to create new data, you should use post method,
Route::post('livro', 'LivroController#store');
public function store(Request $request) {
If you want to update exist data you should use put method,
Route::put('livro/{id}', 'LivroController#update');
public function update(Request $request, $id) {
You can use this package https://github.com/durmus-aydogdu/laravel-resource for rest calls. This package highly customizable for rest and resource calls.
Is better that you use controllers type resources and for this case the put method. Also you should validate the request. For example:
public function update(Request $request, $id)
{
$livro = Livro::findOrFail($id);
$validator = Validator::make($request->all(), [
'livro_id' => 'required',
'nome' => 'required',
'descricao' => 'required',
]);
if ($validator->fails()) {
return response()->json(['errors'=>$validator->messages()],Response::HTTP_UNPROCESSABLE_ENTITY);
}else{
$livo->update($request->all());
return response()->json(['livro'=>$livro], Response::HTTP_OK);
}
}

Laravel - Change URL parameters using GET

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');
}
// ...
}

Resources