Posting JSON objects to Symfony 2
If you want to retrieve data in your controller that's been sent as standard JSON in the request body, you can do something similar to the following:
public function yourAction(){ $params = array(); $content = $this->get("request")->getContent(); if (!empty($content)) { $params = json_decode($content, true); // 2nd param to get as array }}
Now $params
will be an array full of your JSON data. Remove the true
parameter value in the json_decode()
call to get a stdClass
object.
I wrote method to get content as array
protected function getContentAsArray(Request $request){ $content = $request->getContent(); if(empty($content)){ throw new BadRequestHttpException("Content is empty"); } if(!Validator::isValidJsonString($content)){ throw new BadRequestHttpException("Content is not a valid json"); } return new ArrayCollection(json_decode($content, true));}
And I use this method as shown below
$content = $this->getContentAsArray($request);$category = new Category();$category->setTitle($content->get('title'));$category->setMetaTitle($content->get('meta_title'));
javascript on page:
function submitPostForm(url, data) { var form = document.createElement("form"); form.action = url; form.method = 'POST'; form.style.display = 'none'; //if (typeof data === 'object') {} for (var attr in data) { var param = document.createElement("input"); param.name = attr; param.value = data[attr]; param.type = 'hidden'; form.appendChild(param); } document.body.appendChild(form); form.submit();}
after some event (like a click on "submit"):
// products is now filled with a json arrayvar products = jQuery('#spreadSheetWidget').spreadsheet('getProducts');var postData = {'action': action,'products': products}submitPostForm(jQuery('#submitURLcreateorder').val(), postData);
in the controller:
/** * @Route("/varelager/bestilling", name="_varelager_bestilling") * @Template() */ public function bestillingAction(Request $request) { $products = $request->request->get('products', null); // json-string $action = $request->request->get('action', null); return $this->render( 'VarelagerBundle:Varelager:bestilling.html.twig', array( 'postAction' => $action, 'products' => $products ) ); }
in the template (bestilling.html.twig in my case):
{% block resources %} {{ parent() }} <script type="text/javascript"> jQuery(function(){ //jQuery('#placeDateWidget').placedate(); {% autoescape false %} {% if products %} jQuery('#spreadSheetWidget').spreadsheet({ enable_listitem_amount: 1, products: {{products}} }); jQuery('#spreadSheetWidget').spreadsheet('sumQuantities'); {% endif %} {% endautoescape %} }); </script> {% endblock %}
Alrite, I think that's what you wanted :)
EDITTo send something without simulating a form you can use jQuery.ajax().Here is an example in the same spirit as above which will not trigger a page refresh.
jQuery.ajax({ url: jQuery('#submitURLsaveorder').val(), data: postData, success: function(returnedData, textStatus, jqXHR ){ jQuery('#spreadSheetWidget').spreadsheet('clear'); window.alert("Bestillingen ble lagret"); // consume returnedData here }, error: jQuery.varelager.ajaxError, // a method dataType: 'text', type: 'POST'});