oTree Forum >

Is it possible to stop vars_for_template variables from re-loading?

#1 by jackrymac

Hi,

As part of a choice experiment I have a table which presents multiple profiles, participants then select the one they prefer and move onto the next part. This process is repeated numerous times and I vary the profiles each time. However, I've found that you can refresh the page (button or F5 etc) and it cycles through to the next profile and so on.
I want to stop this occurring. I use vars_for_template to pass the values through to the html page, I'm now aware otree docs say they re-execute when the page is refreshed, but I've also used js_vars instead and I get the same issue.

I know I can't completely prevent users refreshing a browser if they want (there's a couple ways to stop them using F5 or it refreshing on form submission but no way to completely prevent it), so I'm hoping there is a way to prevent vars_for_template from re-executing?

Thanks in advance :)

#2 by BonnEconLab

I have encountered similar issues before. This is why I now avoid putting draws of random variables, incrementing counts, adding payoffs, etc. in vars_for_template, js_vars, and is_displayed.

One solution would be that you move your code that cycles through the profiles to before_next_page() of the previous page. The code will then be executed only once. See https://otree.readthedocs.io/en/latest/pages.html#before-next-page.

Alternatively, before the page that displays the desired information to your participants, you could insert a separate page that does not display anything to the participants and that only performs your calculations. (Set timeout_seconds = 0.5 or so for that blank page so that participants do not have an opportunity to refresh it.)

#3 by gr0ssmann

Instead of

    def vars_for_template(player):
        do_something()
        
        return something

do

    class Player:
        …
        
        calculation_ran = models.BooleanField(initial = False)


    def vars_for_template(player):
        if not player.calculation_ran:
            do_something()
            
            player.participant.vars["calculation_result"] = something
            player.calculation_ran = True
        
        return player.participant.vars["calculation_result"]

#4 by jackrymac

@BonnEconLab thank you very much for the insight, nice to know it's not just me. Thanks for the multiple solutions! I think I'll likely be using before_next_page() a lot more often now.

@gr0ssman that's a very elegant solution and it's exactly what I was after. I've tried it and it works perfectly, thanks heaps!

I really appreciate the quick help from you both, it's awesome :)

Write a reply

Set forum username