Serge Poele
Serge Poele

Reputation: 117

Pass dict to controller

I am writing to get some help to "get unstuck". I can't figure out how to pass a dict as an argument to a controller in web2py.

Goal: I need to pass a html5 sessionStorage to a web2py controller to validate it and use it to generate order cart.

Here is what I have: I have a page that's a catalogue of products. I use html5 sessionStorage to collect the order. I looks like this:

{id:qty} e.g. {"1":"32", "15":"50"}

Then I have the following

 jQuery('#cart').click(
        function() {
            alert("sending cart to server via ajax");
            var order = JSON.stringify(sessionStorage);
            console.log(order);

            jQuery.ajax({
                type: 'POST',
                url: '/app/default/generateCart',
                contentType: "application/json; charset=utf=8",
                data: order,
                dataType: 'json',
                success: function(data) {alert('sent to server');}
            });
        });

This correctly sends data to the server where I use request.vars

So the question is: how can I pass this dict-like structure to the controller? I could use JS to generate the link and put a whole dict in it, but that seems insecure and looks like bad practice.

I did read the book, but I apologize in advance: I have a bit of mental block on this problem and cannot see beyond what I did, which is: (1) - I send ajax to the controller above: generateCart() - generateCart() saves request.args into session.order, which cart() controller tries to retrieve from. In cart() session.order is empty. I may not fully understand how session works. (2) - I tried making ajax to the same controller cart(), but that also does not work - it's empty

I would appreciate a kick in the butt on what the practice here and probably a book reference I missed. But key qn is: How do I pass a dict to a controller?

PS: Yes, I am novice in software design and web development. I am trying to follow docs, but I think I got stuck in my head (so to speak). Thank you.

Upvotes: 0

Views: 350

Answers (1)

Serge Poele
Serge Poele

Reputation: 117

The quick answer to this question is: ajax is the right way to go. I was not doing it right. Here is the corrected code:

// ajax request to server
function sendRequest() {
    var order = JSON.stringify(sessionStorage);
    console.log(order);

    jQuery.ajax({
        type: 'POST',
        url: '/app/default/generateCart',
        contentType: 'application/json; charset=utf-8',
        data: order,
        dataType: 'text',
        success: function (data) {
            console.log('callback success');
        },
        error: function() {
            console.log('callback failed');
        }
    });
}

One thing I learned from this is that the callback may fail even if data has successfully arrived to the server. The reason for this is the dataType. I specified dataType as JSON initially and that's what the callback expected. But web2py did now send the call back with JSON, but text. So since that's not what JS expected, it failed. I think it comes back with code other than 200, but I cannot be trusted on this. So, I think you need to know what the callback data type is.

So, looks like generating JSON and sending it over IS in fact the best (or the simplest) way to send complex data to the server. Although, obvious, it took some reading and testing for a noob.

This SO post also massively helped: How do I return the response from an asynchronous call?. Thanks to Felix Kling for a great summary.

Upvotes: 0

Related Questions