1

I have a Django template with an AJAX menu (where clicking on different menu items reloads a part of the page). Each menu click invokes a Django view function through AJAX and returns some data to be shown on the page.

I am loading all the JS required for all the menu items in the main page only (as I learnt that it is not a good idea for AJAX to return JS in a <div> and then use eval() to execute it). Since I am loading all the JS on the menu's main page only, the data obviously isn't there for other menu options at start since it will come later when the corresponding view is invoked (when the menu option is clicked)

Because of that, code like the one below gives a syntax error on the console since JS is parsed the very first time only.

<script> var data = {{se_data|safe}}; </script>

Now I am not able to use the data returned from the view, even after I click the menu options, since the JS parsing failed in the first place. I tried using if to execute the code only when the corresponding menu option is selected but that too does not work since the parser just parses everything.

I have been trying different methods to get around the issue but cant seem to find an efficient way to solve this. An alternative could be to have the view function return all the data at first only, but I fear that the menu options and the data returned may grow over time, hence delaying the initial load of the main menu page.

This is the ajax menu's click function:

$(".ent-menu li a").click(function(e) {
    e.preventDefault(); // prevent from going to the page mentioned in href
    // get the href
    var href = $(this).attr("href");

    $("#data_container").load(href, function() {
        load_data(); //this function uses the data variable defined earlier
    });
});

Error I see in the console when loading the menu's main page:

Uncaught SyntaxError: Unexpected token ;     at line 1110
data = ;

since the data is not available yet.

6
  • If there's never going to be any data on the first load, what's the point of that var data = {{se_data|safe}}; line? Why have it at all? Commented Apr 21, 2017 at 8:11
  • because I need the data later when the corresponding menu option is clicked. Since a menu click is an AJAX call, if I return js there, then I'll have to go the eval() route to execute it which I guess is considered unsafe Commented Apr 21, 2017 at 8:13
  • 1
    That doesn't make sense. Your question says there will never be any data at first. And the Ajax call later will return that data anyway. (Also, I don't understand what you mean about eval; the data is being returned by the Ajax call, you don't need to eval it.) Commented Apr 21, 2017 at 8:14
  • I meant that I will need js to assign the returned data to a js variable. Ajax returns the data but I will need to assign it to a js variable in order to use it. That assignment will require javascript and hence eval()? Commented Apr 21, 2017 at 8:20
  • Why? Presumably it's JSON (if not, why not?) so you should use JSON.parse(). Commented Apr 21, 2017 at 8:29

1 Answer 1

1

As discussed, you should use JSON to send the data from Python to JS; use JSON.parse() to deserialize the data for use in your JS.

Sign up to request clarification or add additional context in comments.

1 Comment

I am now using JSONResponse to fetch the data but I realised a trade-off is that now I have to use two AJAX requests (one to get the template (with HTML) for that menu option and another to get the JSON). Ideally, I could combine the two by sending JSON as context in render() from the view but then I wont be able to parse it since the template variable would be available in the <div> within the HTML returned by AJAX (which wouldnt evaluate JSON.parse() unless I use eval()). Do you agree?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.