Posting JSON objects to Symfony 2
Solution 1
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.
Solution 2
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'));
Solution 3
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 array
var 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 :)
EDIT To 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'
});
Comments
-
greg almost 2 years
I'm working on a project using Symfony 2, I've built a bundle to handle all my database services which passes JSON data back and forward.
My Problem/Question:
Is it possible to post a straight up JSON object? Currently I'm spoofing a normal form post for my ajax calls by giving the object a name
json={"key":"value"}
if I don't give it a name I can't seem to get the data from the Symfony request object$JSON = $request->request->get('json');
I want to be able to use the one service bundle to handle both data coming from AJAX calls, or a normal Symfony form. Currently I'm taking the submitted Symfony form, getting the data then using JSON_ENCODE, I just can't work out how to post the data through to my services controller which is expecting request data.
To summarise:
I want Symfony to accept a JSON post object rather than a form.
I want to pass the JSON object between controllers using Request/Response
If I'm going about this all wrong, feel free to tell me so!
-
greg about 12 yearsThanks for the speedy response! Essentially you are still submitting a normal form with javascript, that is kind of what i'm doing at the moment, I was wondering whether it was possible to directly post the JSON object without simulating a form, if not no drama. Also, once I have the JSON object in Symfony, is it possible to send it off to another service as a Request object?
-
Ярослав Рахматуллин about 12 yearsI addressed your comment in my edit. I'm not quite sure how to do ajax stuff without jQuery, so ill leave that to you. To send someone to another controller you can redirect them there. This is covered in symfony.com/doc/2.0/book/controller.html under Redirecting and Forwarding. Good luck!
-
greg about 12 yearsThank you again, I should have been a little clearer, I can submit the object no problems, I just can't work out how to retrieve it in the controller without it having a name
-
greg about 12 yearsThanks for the response. I actually got it working over the weekend this way: $JSON = file_get_contents("php://input"); Any problems doing it this way?
-
richsage about 12 years
php://input
is a one-time read only. Once you've read the content, it's not available to read again unless you pass that data around. Using the Symfony2 Request object ensures that you can get the data again during a request should you need to, without passing eg your$JSON
variable around. -
greg about 12 yearsThanks for the explanation! I have changed to your method and it's working perfectly. Thank you.
-
greg about 12 yearsOne small typo with the answer. The function needs the request parameter: public function yourAction(Request $request)
-
richsage about 12 years
-
Vitaliy Lebedev almost 11 yearsthere is one problem with this one: you can't bind such request to a form. Is there a way to do so ?
-
Hugo Nogueira almost 10 yearsThanks for your answer. Did a lot of search before landing here to discover ->getRequest()->getContent() to get my Request Payload parameters. Thanks!
-
Bill'o over 9 years$request->request->get('action', null) equals to $request->request->get('action') of course
-
Felix Aballi over 9 yearsIf you use JSON.stringify({'key1': 'value1'}) in ajax request. The controller will receive it as json object, the other case sends: "key1=value1&key2=value2", query string. And will be necessary use the $request->get('key1'). I think the first one is cleaner.
-
Felix Aballi over 9 yearsIf you use JSON.stringify({'key1': 'value1'}) in ajax request. The controller will receive it as json object, the other case sends: "key1=value1&key2=value2", query string. And will be necessary use the $request->get('key1'). I think the first one is cleaner.
-
Mohamed Radhi Guennichi over 6 yearsThe validator class exists by default on symfony?
-
Ярослав Рахматуллин about 6 yearsarrays don't have methods, bro.
-
Farid Movsumov about 6 yearsArrayCollection is a class.
-
Girts Strazdins over 5 yearsthis solution is deprecated. use solution suggested by Farid instead: use Request $request as parameter for the controller method, then read the JSON body as $request->getContent()