Symfony 3 - How to insert data from Ajax Response to Database - php

I am just starting to use Symfony and I just ran in to this problem and even after houers of research online I can not figure it out.
I am trying to insert data from a ajax request into my database. The ajax request works so far an send the following string
{"description":"","location":"","subject":"asdfasdfdsf","allDay":false,"endTime":"2016-11-22T07:00:00.000Z","startTime":"2016-11-22T06:30:00.000Z","user":"6","calendar":"1","offer":"1","status":"open"}
Here is my ajax request
$.ajax({
type: 'POST',
url: '{{ path('calendar_new') }}',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(newAppointment),
dataType: 'json',
success: function(response) {
console.log(response);
}
});
My controller looks like this
/**
* #Route("/calendar/new", name="calendar_new")
* #Method({"GET", "POST"})
*/
public function calenderNewAction(Request $request)
{
if ($request->isXMLHttpRequest()) {
$content = $request->getContent();
if (!empty($content)) {
$params = json_decode($content, true);
$new = new timeEntry;
$new->setDescription($params->get('description'));
$new->setLocation($params->get('location'));
$new->setSubject($params->get('subject'));
$new->setAllDay($params->get('allDay'));
$new->setEndTime($params->get('endTime'));
$new->setStartTime($params->get('startTime'));
$em = $this->getDoctrine()->getManager();
$calendar = $em->getRepository('AppBundle:calendar')
->findOneBy(['id' => 1]);
$offers = $em->getRepository('AppBundle:offer')
->findOneBy(['id' => 1]);
$new->setCalendar($calendar);
$new->setOffer($offers);
$new->setUser($this->getUser());
$em->persist($new);
$em->flush();
}
return new JsonResponse(array('data' => $params));
}
return new Response('Error!', 400);
}
After i try it i get the following error
Call to a member function get() on array
So the $params varible actually returns a object with all the data inside but I don't know how to set my Database variables with these values.

I figured it out.
As mentioned by Cerad I called a method on an array which was the mistake.
Here is my now working controller.
/**
* #Route("/calendar/new", name="calendar_new")
* #Method({"GET", "POST"})
*/
public function calenderNewAction(Request $request)
{
if ($request->isXMLHttpRequest()) {
$content = $request->getContent();
if (!empty($content)) {
$params = json_decode($content, true);
$new = new timeEntry;
$new->setDescription($params['description']);
$new->setLocation($params['location']);
$new->setSubject($params['subject']);
$new->setAllDay($params['allDay']);
$new->setEndTime(new \DateTime($params['endTime']));
$new->setStartTime(new \DateTime($params['startTime']));
$em = $this->getDoctrine()->getManager();
$calendar = $em->getRepository('AppBundle:calendar')
->findOneBy(['id' => 1]);
$offers = $em->getRepository('AppBundle:offer')
->findOneBy(['id' => 1]);
$new->setCalendar($calendar);
$new->setOffer($offers);
$new->setStatus('Open');
$new->setUser($this->getUser());
$em->persist($new);
$em->flush();
}
return new JsonResponse(array('data' => $params));
}
return new Response('Error!', 400);
}

Related

Laravel returns 302 error when trying to send POST request to API route from Laravel Controller

A 302 error is returned when I'm trying to post to API Route, only in the second Post, using the function insereTelefone. When I'm using the Postman, it's working properly, so I think the problem is with Route, but I don't know what. I'm a newbie at the Laravel, so I'm learning how to implement things.
Here is the controller who calls the POST API:
class IndexClientes extends Controller
{
public function index()
{
$request = Request::create('/api/clientes', 'GET');
$response = Route::dispatch($request);
$clientes = json_decode($response->getContent(), true);
return view('index', compact('clientes'));
}
public function create()
{
return view('formulariocliente');
}
public function store(Request $request)
{
$nome = $request->nome;
$cpf = $request->cpf;
$email = $request->email;
$numerosTelefone = $request->telefone;
$tiposTelefone = $request->tipoTelefone;
$request = Request::create('/api/clientes', 'POST', array(
"nome" => $nome,
"cpf" => $cpf,
"email" => $email
));
$responseInicial = Route::dispatch($request);
$response = json_decode($responseInicial->getContent(), true);
$status = json_decode($responseInicial->status(), true);
if ($status !== 200) :
echo "ERRO";
die();
endif;
$idCliente = $response['id'];
if (!empty($numerosTelefone)) :
$i = 0;
foreach ($numerosTelefone as $numeroTelefone) :
$tipoTelefone = (int)$tiposTelefone[$i];
$numeroTelefone = (int)$numeroTelefone;
if (!empty($tipoTelefone) && !empty($numeroTelefone)) :
return self::insereTelefone($idCliente, $tipoTelefone, $numeroTelefone);
endif;
$i++;
endforeach;
endif;
}
public function insereTelefone($idCliente, $tipoTelefone, $numTelefone)
{
$array = array(
"cliente_id" => $idCliente,
"telefone_tipo_id" => $tipoTelefone,
"numero" => $tipoTelefone
);
$request = Request::create('api/telefones', 'POST', $array);
$responseInicial = Route::dispatch($request);
$response = json_decode($responseInicial->getContent(), true);
$status = json_decode($responseInicial->status(), true);
return $status;
}
}
TelefonesController.php
public function store(Request $request)
{
$request->validate(
[
'cliente_id' => 'required',
'telefone_tipo_id' => 'required',
'numero' => 'required|max:11'
]
);
}
api.php
Route::apiResource('telefones', \App\Http\Controllers\TelefonesController::class);
A 302 response usually means your request is being redirected by laravel.
If you are expecting a json response, you need to set the Accept: 'application/json' header along with your request just after the line:
$request = Request::create('api/telefones', 'POST', $array );
$request->headers->set('Accept', 'application/json');
the first
Route::dispatch
was redirecting the page, when I'm was trying to run the second Route::dispatch Laravel returns 302, to solve this I'm using the
app()->handle()
in the function insereTelefone to back to handle the request.
public function insereTelefone($idCliente, $tipoTelefone, $numTelefone) {
$array = array(
"cliente_id" => $idCliente,
"telefone_tipo_id" => $tipoTelefone,
"numero" => $numTelefone
);
$request_telefone = Request::create('api/telefones', 'POST', $array );
$responseInicial = app()->handle($request_telefone);
$status = json_decode($responseInicial->status(),true);
return $status;
}

Can not access request data from ajax post request in symfony 3

I am using symfony 3.4 and I would like to send some data to controller but I do not know why I can not access it like it is show in symfony documentation:
This is my js function:
function sendQuantitiesToController() {
// Validate data
var validation = validateQuestionnaireReviewFormData();
if (validation === false) {
return false;
}
// Get form data
var data = getReviewFormComponentsData();
var id = document.getElementById('questionnaire-id').innerText;
// Send data
$.post("http://localhost:8000/questionnaire/"+id+"/review", {
components: data.components,
optional_components: data.optional_components
},
function(response, status) {
if (status == 'success') {
return true;
} else {
return false;
}
});
}
And this is my Controller function:
/**
* Questionnaire result review
*
* #Route("/questionnaire/{id}/review", name="_questionnaire_review", requirements={"id" = "\d+"})
* #Template()
*/
public function questionnaireReviewAction(Request $request, $id)
{
$form = $this->createForm(ResultOverviewType::class, $result);
$contactForm = $this->createForm(ContactType::class, $contact);
if ($request->isMethod('POST')) {
// Get data from request
$components = $request->request->get('components');
$optionalComponents = $request->request->get('optional_components');
...
}
}
return [
'form' => $form->createView(),
'contactForm' => $contactForm->createView(),
'questionnaire' => $questionnaire
];
}
Twig Template:
{{ form_start(contactForm, {'attr': {'onsubmit': 'return sendQuantitiesToController();'}}) }}
{{ form_widget(form) }}
{{ form_widget(contactForm) }}
{{ form_end(form) }}
The problem is that the $request->request->get('components') in controller is always null, but I checked getReviewFormComponentsData() with console.log and there is data there so the problem is probably with ajax post request. What I am doing wrong? Can anyone help me?
Thanks for help!
To get request data from ajax request in Symfony Controller you should simply do that:
public function questionnaireReviewAction(Request $request, $id)
{
$form = $this->createForm(ResultOverviewType::class, $result);
$contactForm = $this->createForm(ContactType::class, $contact);
if ($request->isMethod('POST')) {
// Get data from request
$data = $request->getContent();
$data = json_decode($data, true);
$components = $data['components'];
$optionalComponents = $data['optional_components'];
...
}
...
}

How to pass Array in symfony route?

I have a function in my controller that takes an array as input. The value is passed from ajax. At the moment it is not being decoded correctly.
/**
* #Route("/userLogin/{params}", name="userLogin", methods={"POST"})
* #param UserdbRepository $repository
* #param $params
* #return \Symfony\Component\HttpFoundation\Response
*/
public function userLogin(UserdbRepository $repository, $params) {
$email = $params[0];
$pass = $params[1];
print_r($params); // output correct value test#test.com
echo $params[0]; // output t
echo $email; // output t
.... rest of code
}
js:
const array = [ 'email', 'pass' ]
$.ajax({
url: `/userLogin/${array}`,
type: "post",
dataType: 'json'
})
Use Request component Symfony\Component\HttpFoundation\Request you can autowire it: public function userLogin(UserdbRepository $repository, Request $request)
Example 1: fetch params from requestBody:
$email = $request->request->get('email', null);
$email will be null if 'email' parameter not provided in request
don't forget to pass data property in your ajax request
const requestBody = {
'email': 'asd#example.com',
'pass': '123',
};
$.ajax({
url: `/userLogin/`,
type: "post",
data: requestBody,
});
Note: don't send data in json format. Also you can remove {params} from your #Route pattern and $params argument.
Example 2: fetch 'email' param from queryString:
$email = $request->query->get('email', null);
https://symfony.com/doc/current/components/http_foundation.html

php/symfony: retrieving an attribute in the url for POST/PUT api

For a datatable I use in a page (webix datatable), I have to use a REST API.
My url is for example: http://localhost:8000/trial/1
In this page to make the api call I use the following:
save: "rest->{{ path('api_i_post') }}",
url: "rest->{{ path('erp_interventionapi_get', { trialid: trial.id })
With the GET method, I retrieve for a trial (/trial/1), many interventions which are loaded from a database and filled in the datatable.
With this datatable, I'm able to "add a new row". It uses the POST method (save: "rest->{{ path('api_i_post') }}")
When I add a new row, I'd like to be able to get the field trial_id filled in automatically, depending from where I add a new row in the datatable (for /trial/1, trial_id = 1) but I don't know how to retrieve this attribute (or the trial object id), in a POST and a PUT.
My postAction:
/**
* #Rest\Post("/api_i/", name="api_i_post")
*/
public function postAction(Request $request)
{
$data = new Intervention;
$id = $request->get('id');
$action = $request->get('action');
$daadala = $request->get('daadala');
$date = $request->get('date');
$week = $request->get('week');
$infopm = $request->get('info_pm');
$comment = $request->get('comment');
$location = $request->get('location');
$trial = $request->get('trialid');
$data->setAction($action);
$data->setDaadala($daadala);
$data->setDate($date);
$data->setWeek($week);
$data->setWho($infopm);
$data->setInfoPm($comment);
$data->setComment($location);
$data->setTrial($trial);
$em = $this->getDoctrine()->getManager();
$em->persist($data);
$em->flush();
$lastid = $data->getId();
$response=array("id" => $id, "status" => "success", "newid" => $lastid);
return new JsonResponse($response);
$view = View::create(array("newid" => $lastid, "id" => $id, "status" => "success"));
return $this->handleView($view);
}
And my putAction
/**
* #Rest\Put("/api_i/{id}")
*/
public function putAction(Request $request)
{
$data = new Intervention;
$id = $request->get('id');
$action = $request->get('action');
$daadala = $request->get('daadala');
$date = $request->get('date');
$week = $request->get('week');
$infopm = $request->get('info_pm');
$comment = $request->get('comment');
$location = $request->get('location');
$sn = $this->getDoctrine()->getManager();
$intervention = $this->getDoctrine()->getRepository('ErpBundle:Sponsor')->find($id);
if (empty($intervention)) {
return new View("Sponsor not found", Response::HTTP_NOT_FOUND);
}
$intervention->setAction($action);
$intervention->setDaadala($daadala);
$intervention->setDate($date);
$intervention->setWeek($week);
$intervention->setWho($infopm);
$intervention->setInfoPm($comment);
$intervention->setComment($location);
$sn->flush();
$response=array("id" => $id, "status" => "success");
return new JsonResponse($response);
}
Can you help me with this issue?
Thank you very much
Update of my code after the replys:
I have update this in my twig template:
save: "rest->{{ path('api_i_post', { trialid: trial.id }) }}",
If I look in the profiler of the ajax request, I see it is here:
Key Value
trialid "1"
But I still don't figure how to get it in my post request (the trial_id is still null right now)
I've tried the following:
/**
* #Rest\Post("/api_i/", name="api_i_post")
* #Rest\RequestParam(name="trialid")
*
* #param ParamFetcher $paramFetcher
* #param Request $request
*/
public function postAction(Request $request, ParamFetcher $paramFetcher)
{
$data = new Intervention;
$id = $request->get('id');
$action = $request->get('action');
$daadala = $request->get('daadala');
$date = $request->get('date');
$week = $request->get('week');
$infopm = $request->get('info_pm');
$comment = $request->get('comment');
$location = $request->get('location');
$trial = $paramFetcher->get('trialid');
$data->setAction($action);
$data->setDaadala($daadala);
$data->setDate($date);
$data->setWeek($week);
$data->setWho($infopm);
$data->setInfoPm($comment);
$data->setComment($location);
$data->setTrial($trial);
$em = $this->getDoctrine()->getManager();
$em->persist($data);
$em->flush();
$lastid = $data->getId();
$response=array("id" => $id, "status" => "success", "newid" => $lastid);
return new JsonResponse($response);
$view = View::create(array("newid" => $lastid, "id" => $id, "status" => "success"));
return $this->handleView($view);
}
I guess you are using the FosRestBundle, if so, you can use annotations to retrieve your url parameters :
/**
* #Rest\Put("/api_i/{id}", requirements={"id" = "\d+"})
*/
public function putAction($id)
{
// you now have access to $id
...
}
If you want to allow additionnal parameters for your route but not in the uri, you can use RequestParam with annotations :
/**
* #Rest\Put("/my-route/{id}", requirements={"id" = "\d+"})
*
* #Rest\RequestParam(name="param1")
* #Rest\RequestParam(name="param2")
*
* #param ParamFetcher $paramFetcher
* #param int $id
*/
public function putAction(ParamFetcher $paramFetcher, $id)
{
$param1 = $paramFetcher->get('param1');
....
}
Be sure to check the fosRestBundle documentation to see everything you can do (such as typing the params, making them mandatory or not, etc...)
To get post value you need to do this inside your post action:
public function postAction(Request $request)
{
$postData = $request->request->all();
Then you have an array of value like:
$id = $postData['id'];
For the PUT you need this:
public function putAction(int $id, Request $request)
{
$putData = json_decode($request->getContent(), true);
And then to treieve a value like this:
$id = $putData['id'];

Symfony2 - KnpPaginator - AJAX/Embedded Controller

I'm having an issue with Knp, an AJAX request, and a filter. I think I'm doing something very wrong here, but I am not sure how exactly KnpPaginator works internally, and I don't have the time to figure it out on this project.
Anyway, basically, my page has an embedded controller which renders a table on the page. When paginator is called from twig, it returns the route to the container page, which results in paginator failing to work with my GET requests to that uri.
I'm not sure if any of you have come across this - I'm happy to listen if there is a better solution to the problem (I'm quite sure there is). Here is my code:
CONTROLLER
/**
* Just a shell page
*
* #Route("/postmanagement/index")
* #Template()
*
* #return array
*/
public function indexAction()
{
$form = $this->createForm(new FilterPostsType(), null, array(
'action' => $this->generateUrl('myblog_admin_postmanagement_filterposts'),
'method' => 'POST'
)
);
return array(
'form' => $form->createView()
);
}
/**
* Returns active posts and comments
*
* #param Request $request
*
* #return array
*/
public function defaultAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$posts = $em->getRepository('ModelBundle:Post')->findBy(array(
'active' => true
)
);
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate($posts, $request->query->get('page', 1), 10);
return $this->render("AdminBundle:PostManagement:_ajax-panel.html.twig", array(
'isPost' => true,
'posts' => $posts,
'pagination' => $pagination
)
);
}
/**
* #param Request $request
*
* #Route("/postmanagement/filter")
*
* #return array
*/
public function filterPostsAction(Request $request)
{
$form = $this->createForm(new FilterPostType(), null, array(
'action' => $this->generateUrl('myblog_admin_postmanagement_filterposts'),
'method' => 'POST'
)
);
// if ($request->isMethod('POST')) {
$posts = null;
$form->handleRequest($request);
$data = $form->getData();
$posts = $this->get('myblog.admin_manager')->filterPosts($data);
switch ($data['type']) {
case 'post':
$isPost = true;
$isComment = false;
break;
case 'comment':
$isPost = false;
$isComment = true;
break;
}
// }
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate($posts, $request->query->get('page', 1), $data['maxresults']);
if (is_null($posts)) {
return new NotFoundHttpException();
} else {
return $this->render('AdminBundle:PostManagement:_ajax-panel.html.twig', array(
'posts' => $posts,
'isPost' => $isPost,
'isComment' => $isComment,
'pagination' => $pagination
)
);
}
}
I'm not posting the view here, since it is a simple render(controller(MyBundle:Controller:myAction)). As you can see, there is a form I'm submitting on the page, to filter the posts. That also poses a problem, since it seems paginator doesn't keep the query after I've run it through the filter.
Thanks for any help! I would love if someone has done this before and has come up with a better solution than my rather convoluted one (which also involves too many queries for my liking).
I figured it out.
If anyone else would like to paginate with InfiScr trigger + KNPPaginatorBundle + filter (PHP), use this JS:
/**
* Load more pagination handler
*/
var AjaxPagination = function (options) {
AjaxProt.call(this, options);
this.filter = options.filter;
this.toJoinEl = options.toJoinEl;
this.containerEl = options.containerEl;
this.navContainer = options.navContainer;
this.nextSelector = options.nextSelector;
this.uri = options.uri;
};
AjaxPagination.prototype = Object.create(AjaxProt.prototype);
AjaxPagination.prototype.init = function () {
var thisObj = this,
uri = thisObj.uri;
$(thisObj.navContainer).hide();
$(document).on(thisObj.event, thisObj.targetEl, function (e) {
e.preventDefault();
thisObj.ajaxRequest(uri);
});
};
AjaxPagination.prototype.ajaxRequest = function (uri) {
var thisObj = this,
page = $(this.nextSelector).attr('href').match(/\d+$/);
$('#filter_bets_page').val(page);
var data = $(this.filter).serialize(),
method = this.method;
console.log(data);
$.ajax({
url: uri,
data: data,
type: method,
success: function (data) {
thisObj.infiScrCallback(data);
}
});
};
AjaxPagination.prototype.infiScrCallback = function(data) {
var thisObj = this;
$(thisObj.navContainer).remove();
if (thisObj.toJoinEl) {
var filteredContent = $("<div>").append( $.parseHTML( data ) ).find( '.findable');
var newPagination = $("<div>").append( $.parseHTML( data ) ).find( 'div.pagination-hidden' );
$(thisObj.toJoinEl).append(filteredContent);
$(thisObj.containerEl).append(newPagination);
} else {
$(thisObj.containerEl).append(data).fadeIn();
}
if (!$(thisObj.nextSelector).length) {
$(thisObj.targetEl).fadeOut();
}
};

Categories