18

I need to store some map parameter in my symfony project, to do this i need to implement some Ajax in my view which will be able to pass some info to the controller.

I read the docs, try to write some code but i can't make it works. And Ajax is really painfull to debug. Here is the controller part :

 /**                                                                                   
 * @Route("/ajax", name="_recherche_ajax")
 */
public function ajaxAction()    
{
    $isAjax = $this->get('Request')->isXMLHttpRequest();
    if ($isAjax) {         
        return new Response('This is ajax response');
    }
    return new Response('This is not ajax!', 400);
}

And the JS :

map.on('zoomend', function(e) {
    // use callback e variable
    console.log('zoom: ' + e.target.getZoom());

    $.ajax({
        type: "POST",
        url: "/recherche/ajax",
        data: {
           zoom: e.target.getZoom()
        },
        dataType: "json",
        success: function(response) {
            console.log(response);
        }
    });

});

I check the url recherche/ajax it does exist and return the 'This is not Ajax' as expected. But the console.log does not return any value...

Is that the right way to do this ?

EDIT : It looks like the controller can't handle POST Request. I tried to modify the annotations to :

 /**                                                                                   
 * @Route("/ajax", name="_recherche_ajax")
 * @Method({"GET", "POST"})
 */

But it returns :

([Semantical Error] The annotation "@Method" in method MySite\SiteBundle\Controller\RechercheController::ajaxAction() was never imported. Did you maybe forget to add a "use" statement for this annotation?) 
Xavier
  • 3,919
  • 3
  • 27
  • 55
  • 1
    Is response outputing `undefined` or nothing is outputed at all ? – Touki Oct 15 '13 at 08:07
  • 1
    I got nothing im my console... – Xavier Oct 15 '13 at 08:08
  • That is most likely due to `FATAL` error in PHP. Try entering ajax request address into browser directly (I know, it's not `POST`) and see if there is some Symfony error... – Jovan Perovic Oct 15 '13 at 08:18
  • 1
    @x_vi_r Open your Network tab in your debugger, process the Ajax request and check the response given by your browser. Check yet if the event is fired, if so, see if a `500` StatusCode is returned. If so, you can verify what happened in your `app/logs` folder. – Touki Oct 15 '13 at 08:21
  • @Touki you was right, it's return a 500 Error. I updated my question – Xavier Oct 15 '13 at 08:54
  • 2
    Then just add `use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;` at the top of your file – Touki Oct 15 '13 at 08:55
  • As a general principle, I suggest you to make your php process communicate, via socket, with another process, and give to it some "debugging" text to write in its terminal. – donkeydown Oct 15 '13 at 09:11

2 Answers2

24

Try this,

/**                                                                                   
 * @Route("/ajax", name="_recherche_ajax")
 */
public function ajaxAction(Request $request)    
{
    if ($request->isXMLHttpRequest()) {         
        return new JsonResponse(array('data' => 'this is a json response'));
    }

    return new Response('This is not ajax!', 400);
}

In case of you sending an Ajax request, you need to return json/plaintext/xml data, and not a whole Response object.

PS: Do not forget to add use statment for Request and JsonResponse

EDIT : As the error message you added says, you need to import the annotation @Method by using :

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

Ahmed Siouani
  • 13,701
  • 12
  • 61
  • 72
sf_tristanb
  • 8,725
  • 17
  • 74
  • 118
  • 1
    I want call actual ajax call from controller. Pls give any suggestion. – Ketav Jan 25 '17 at 06:30
  • You can add `condition="request.isXmlHttpRequest()",` to `@Route` to restrict matching to ajax requests. Similar to how `@Method` works. See: http://symfony.com/doc/current/routing/conditions.html – Will B. May 31 '17 at 16:44
3

I was looking the entire internet and didn't find any solution to similar problem. But i found it-> I had neither issue with the controller, nor the javascript/jquery/ajax nor the security issues. It was in .... wait for it.... in HTML. i had to add type="button" into html tag, otherwise whole page was refreshing. 4 hours wasted on debugging purposes.. but lessons learned.

How to debug problems? 1. Check if ajax is sending post and matching post route on the client side. Firefox -> f12 -> network -> watch the POST events 2. Check the symfony profiler (very usefull tool!) on the -> /app_dev.php/ (dev enviroment) -> Get Request/Response submenu end take last 10, if You see the POST route check closely if its return code and parameters (you wont see response, if its set other than HTML response) 3. In your controller do some action that can be checked if the script inside this route was executed. If so, and You see no response its either on the server side (controller) or client side (twig/ajax/html) 4. Code examples:

Button in html (this was my issue)

<button name="button" id="button" class="button" type="button" value="100"> Click me </button> 

Ajax in html or other included js file:

function aButtonPressed(){
        $.post('{{path('app_tags_sendresponse')}}',
            {data1: 'mydata1', data2:'mydata2'},
            function(response){
                if(response.code === 200 && response.success){
                    alert('success!');
                }
                else{
                    alert('something broken');
                }
            }, "json");
    }

Now.. server side. Controller:

namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class JsonApiController extends Controller
    /**
         * @Route("/api/programmers")
         * @Method("POST")
         */
        public function sendResponse()
        {
            if(isset($_POST['data1'])){
                $json = json_encode(array('data' => $_POST['data1']), JSON_UNESCAPED_UNICODE);
                file_put_contents("test.json", $json);
                return new JsonResponse($json);
            }
            return new Response('didn't set the data1 var.');
        }
    }

File put contents create new file in web directory. If it was matched and file is created that means, that You matched the route, but didn't get the response