Create dynamic request object in Laravel - json

I was looking for help creating an object of the type Illuminate\Http\Request. This article helped me understand the mechanism of the class, but I did not get the desired result.
Create a Laravel Request object on the fly
I'm editing the development code passed to me by the customer. The code has a function that gets a request parameter from vue and translates it to JSON:
$json = $request->json()->get('data');
$json['some_key'];
This code returned an empty array of data:
$json = $request->request->add([some data]);
or
$json = $request->request->replace([some data]);
this one returned an error for missing the add parameter
$json = $request->json->replace([some data]);
A variant was found by trying and errors. Maybe, it help someone save time:
public function index() {
$myRequest = new \Illuminate\Http\Request();
$myRequest->json()->replace(['data' => ['some_key' => $some_data]]);
$data = MyClass::getData($myRequest);
}
..
class MyClass extends ...
{
public static function getData(Request $request) {
$json = $request->json()->get('data');
$json['some_key'];
In addition, there are other fields in the class that you can also slip data into so that you can pass everything you want via Request
$myRequest->json()->replace(['data' => ['some_key' => $some_data]]);
..
$myRequest->request->replace(['data' => ['some_key' => $some_data]]);
..
$myRequest->attributes->replace(['data' => ['some_key' => $some_data]]);
..
$myRequest->query->replace(['data' => ['some_key' => $some_data]]);

$myRequest = new \Illuminate\Http\Request();
$myRequest->setMethod('POST');
$myRequest->request->add(['foo' => 'bar']);
dd($request->foo);
This from the link you shared works, give it a try. Thanks for sharing that link!

Related

Retrieve specific data using JSON decode Laravel

I'm new to Laravel. I need to retrieve specific data from the database using the JSON decode. I am currently using $casts to my model to handle the JSON encode and decode.
This is my insert query with json encode:
$request->validate([
'subject' => 'required|max:255',
'concern' => 'required'
]);
$issue = new Issue;
$issue->subject = $request->subject;
$issue->url = $request->url;
$issue->details = $request->concern;
$issue->created_by = $request->userid;
$issue->user_data = $request->user_data; //field that use json encode
$issue->status = 2; // 1 means draft
$issue->email = $request->email;
$issue->data = '';
$issue->save();
The user_data contains {"id":37,"first_name":"Brian","middle_name":"","last_name":"Belen","email":"arcega52#gmail.com","username":"BLB-Student1","avatar":"avatars\/20170623133042-49.png"}
This is my output:
{{$issue->user_data}}
What I need to retrieve is only the first_name, middle_name, and last_name. How am I supposed to achieve that? Thank you in ADVANCE!!!!!
As per the above code shown by you it will only insert data into the database.For retrieving data you can make use of Query Builder as i have written below and also you can check the docs
$users = DB::table('name of table')->select('first_name', 'middle_name', 'last_name')->get();
I will recommend using Resources. It really very helpful laravel feature. Check it out. It is a reusable class. You call anywhere and anytime.
php artisan make:resource UserResource
Go to your the newly created class App/Http/Resources/UserResource.php and drfine the column you want to have in your response.
public function toArray($request) {
return [
"first_name" => $this->first_name,
"middle_name" => $this->middle_name,
"last_name" => $this->last_name
]
}
Now is your controller you can use the UserResource like folow:
public function index()
{
return UserResource::collection(User::all());
}
Or after inserting data you can return the newly added data(f_name, l_name...)
$user = new User;
$user->first_name= $request->first_name;
$user->middle_name= $request->middle_name;
$user->last_name= $request->last_name;
$user->save();
$user_data= new UserResource($user);
return $user_data;

how to convert DBIx::Class::ResultSet into JSON

I am trying to obtain JSON from a DBIx::Class::ResultSet and I get the exception
encountered object 'Sql2Json::Model::DB::Book=HASH(0x6014f88)',
but neither allow_blessed, convert_blessed nor allow_tags settings are
enabled (or TO_JSON/FREEZE method missing)
The controller class is Books.pm:
package Sql2Json::Controller::Books;
use Moose;
use namespace::autoclean;
use JSON::XS;
BEGIN { extends 'Catalyst::Controller'; }
my $json = JSON::XS->new;
sub list : Local {
my($self, $c) = #_;
$c->stash(books_rs => $c->model('DB::Book'));
$c->stash(books => [$c->stash->{books_rs}->search({}, {order_by => 'name ASC'})]);
$c->stash(json_data => $json->convert_blessed->encode($c->stash->{books}));
$c->forward('View::JSON');
}
__PACKAGE__->meta->make_immutable;
1;
According to this article is enough the encoding of blessed objects:
$json->convert_blessed->encode($c->stash->{books})
Do I missing somethig here?
Almost all the time, the best way to do this is using the get_inflated_column method of the rows returned from a query.
$books = $c->model('DB::Book');
$c->stash(json_data => [map {$_->get_inflated_columns} $books->all]);
$c->forward('View::JSON');

Inserting JSON to DB Using Model in Laravel

I'm trying to use the model create option and this is my array:
$result = array(
'match_id' => $input['id'],
'score' => $input['score'],
'result' => $input['result'],
'headline' => NULL,
'article' => $input['report'],
'tries' => $input['try'],
'try_amount' => $input['tryquant'],
'conversions' => $input['conv'],
'conv_amount' => $input['convquant'],
'penalties' => $input['pens'],
'pen_amount' => $input['penquant'],
'dropgoals' => $input['dgs'],
'dg_amount' => $input['dgquant']
);
Result::create($result);
The contents of some of these are arrays themselves. eg:
$input['penquant'] = [
"4"
]
When I run my code, it saves the data to the DB simply as Array and throws up the following error:
ErrorException in helpers.php line 703: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
Can someone tell me what I'm doing wrong and how to fix it?
Shouldn't have rushed, forgot to use json_encode.
The best is to use mutators and accessors in your model.
example of mutator
// convert pen_amount from snake case to studly case
// The set...attribute (the ... is you field name which is in studly case) helps transform the data before you save it
// into the database
public function setPenAmountAttribute($value)
{
$this->attributes['pen_amount'] = serialize($value);
}
example of an accessor is
// convert pen_amount from snake case to studly case
// the get...Attribute (the ... is you field name which is in studly case) helps you convert the data back to it original state
public function getPenAmountAttribute($value)
{
return unserialize($value);
}
You can use accessors and mutators for all your fields that you want to save as array. This is elegant. No need to manually use json_encode and decode in your controllers.

Cakephp 3 & Ajax, send $.get additional data

I try to send custom data using $.get from jquery but cakephp 3 does not recognize the variables.
Here is my function in controller:
public function view($cat,$id,$page){
$comments = $this->Comments->find('all')->where(['category =' => $cat, 'AND' => ['category_id =' => $id]])->order(['comments.created' => 'DESC'])
->contain([
'Reports' => function($q){return $q->where(['user_id =' => $this->Auth->user('id')]);},
'Chars' => function($q){ return $q->select(['id','name','class','race','level','guild_id', 'user_id'])
->contain(['Guilds' => function($q){ return $q->select(['id','name']);
}]);
}])->limit(3)->page($page);
if($cat == 'Videos'){
$subject = $this->Comments->Videos->get($id);
}
$category = $cat;
$this->set(compact('subject','comments','category'));
}
}
And here's the .js
$('.more').click(function(){
$.get($(this).attr('href'),{cat:'Videos',id:'44',page:'2',function(data){
$('.coms').empty().append(data);
});
return false;
});
And the link:
<?= $this->Html->link('More', ['controller' => 'Comments','action' => 'view'], ['class' => 'btn btn-primary more']) ?>
The fix values in the .js is for the test, it works if I send the data in the link with $.get(href) but I want to know how to pass custom data in the $.get request.
Thank you for your help
CakePHP doesn't magically map query string parameters to method arguments, that's not even supported by routes.
You can access query string paramters via the request object
$this->request->query('cat');
See also http://book.cakephp.org/3.0/en/controllers/request-response.html#query-string-parameters
The solution
Hi, I did a little api to get the data I need from a json array.
So I created an ApiController to do all the ajax requests I need. Here is test example:
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\ORM\TableRegistry;
class ApiController extends AppController
{
public function test($id)
{
$UsersTable = TableRegistry::get('Users');
$users = $UsersTable->find()->where(['id <' => $id]);
$this->set(compact('users'));
}
}
?>
I want to get the list of all my users from an ajax call (that's the worst idea ever but it's just for the test ;))
Now I need to enable json for this view. For this, I need to go in config/routes.php to add this:
Router::scope('/api', function($routes){
$routes->extensions(['json']);
$routes->connect('/test/*', ['controller' => 'Api', 'action' => 'test', '_ext' => 'json']);
});
Now when I go on http://localhost/mywebsite/api/test/100, I have a json array of all the users with an id < 100, ready to get pulled by an ajax script.
'_ext' => 'json'
means you don't have to go on api/test.json to display the json array
Now on a random view in a random controller, I put a button to try all this and I call my javascript file to do my ajax request.
<button class="test">Test button</button>
<?= $this->Html->script('test', ['block' => true]) ?>
Now in my test.js:
$(document).ready(function(){
var value = 100;
$('.test').click(function(){
$.get('/api/test/' + value, function(data){
console.log(data);
});
});
});
I click the button and the log shows an array with all the users I wanted in my console when I push F12 (on chrome).
Hope this will help someone

zend framework 2, return the rendered contents of a view inside a JSON Model

I am trying to create a JsonModel with an item in the variables 'html' containing the current rendered view. I would like to add this code to an event:
rather than this method: How to render ZF2 view within JSON response? which is in the controller, I would like to automate the process by moving it to an Event
I have the strategy in my module.config.php:
'strategies' => array(
'ViewJsonStrategy',
)
I have set up a setEventManager in the controller:
$events->attach(MvcEvent::EVENT_RENDER, function ($e) use ($controller) {
$controller->setRenderFormat($e);
}, -20);
Is this the best event to attach it to? would the RENDER_EVENT be better?
Now I would like to change the render of the page based on !$this->getRequest()->isXmlHttpRequest(), (commented out for debug)
public function setRenderFormat($e)
{
//if(!$this->getRequest()->isXmlHttpRequest())
//{
$controller = $e->getTarget();
$controllerClass = get_class($controller);
//Get routing info
$controllerArr = explode('\\', $controllerClass);
$currentRoute = array(
'module' => strtolower($controllerArr[0]),
'controller' => strtolower(str_replace("Controller", "", $controllerArr[2])),
'action' => strtolower($controller->getEvent()->getRouteMatch()->getParam('action'))
);
$view_template = implode('/',$currentRoute);
$viewmodel = new \Zend\View\Model\ViewModel();
$viewmodel->setTemplate($view_template);
$htmlOutput = $this->getServiceLocator()->get('viewrenderer')->render($viewmodel, $viewmodel);
$jsonModel = new JsonModel();
$jsonModel->setVariables(array(
'html' => $htmlOutput,
'jsonVar1' => 'jsonVal2',
'jsonArray' => array(1,2,3,4,5,6)
));
return $jsonModel;
//}
}
Strangely, (or not) this code works and produces the $jsonModel, however is doesn't overwite the normal HTML view with the json, but the same code (without the event) in a controller method, overwrites perfectly.
p.s Is there a better method to do the whole concept?
p.p.s how can I obtain the current View Template from within the controller, without resorting to 8 lines of code?
Thanks in advance!
Aborgrove
you are returning the view model from an event I thinks this doesn't have any effect in current viewmanager view model, fetch the current viewmodel from viewmanager and call setTerminal(true). or replace the created jsonmodel using the viewmanager