Return javascript variable back to Form

Rookie question here: I’m trying to get the python in my form to call a javascript function that gets the user’s IP and then returns it back to the python code of the form.

I can only get the first half of this to work. Meaning I successfully call my javascript function “loadIP” from the python shown below and it captures the user’s IP address. However, at the end of my javascript function, when I try to “return ipaddress;” back to the python that called it, it keeps spitting out None as the response. Can custom javascript functions not return results to the python code that calls them?

def form_show(self, **event_args):
  collectIP=self.call_js("loadIP")
  print(collectIP)

Yep, returning data from JS back to Python is certainly possible.

Please read these docs:
https://anvil.works/docs/client/javascript

In particular, anvil.call() calls back to Python.

Not sure why this wouldn’t work.

Do you have a clone or the JavaScript code you’ve written?

Thank you for your quick reply.

From your answer, it sounds like using a simple “return” from the javascript code doesn’t work.

I had already read through the documentation you cited and tried the anvil.call() but without success.I think my fundamental problem is that I don’t understand the bridge between the python and the custom javascript sections. And having almost no jquery experience, I’m probably further behind than the average Anvil user.

I was able to find a thread that I’m pretty sure points to my issue:

In it meredydd describes how the anvil.call() needs to know which form element the method is attached to, thus the use of anvil.call(this, 'submit_clicked', formData); doesn’t work unless the “this” is associated with a DOM element. And that’s the rub. Unlike the example where they are discussing a clickable link providing that DOM reference, I’m just trying to get my javascript function to run and return the ip address without any particular link or button being fired by the user. I was hoping meredydd in his explanation would describe some kind of simple assignment of “this” just to the page load.

david.wylie describes a work-around using divs to provide a connection to the DOM, and I was able to get that method to work. But it seems strange to me to have to create invisible div elements in my Custom HTML section in order to trick my javascript function to communicate back with the python code. I’d much rather have my javascript write information directly into hidden Label or Textbox Components created/managed by the python code, but I couldn’t figure out how the javascript could get access to them. Especially since it doesn’t seem that the Components support the “id” tag in order to reference them. Like I mentioned earlier, my lack of jquery/DOM manipulation is probably my impediment in this area.

Thanks again for your timely response.

Cheers,

Doug

here is a simple app that returns a value from a javascript function with no problems

https://anvil.works/build#clone:ZCC3CMWDKWOLUHJX=BK7VOUJUN6GYPAV5BJ56JPAR

def form_show(self, **event_args):
  foo = self.call_js('checkJsReturns')
  print(foo) # bar
<script>
function checkJsReturns() {
  return 'bar'
}
</script>

Alternative approaches here:
You can get the ip address from the server

#client
anvil.server.call('get_ip')
#serverside
@anvil.server.callable
def get_ip():
    print(anvil.server.context.ip)

https://anvil.works/docs/server/call-context

4 Likes

Wow, both of those suggestions are great. I tried both of them on a demo app and they worked as advertised.

Your first example proves that simple javascript return statements do work. Still not sure why I couldn’t get it to fire in my original project, but now I have a reason to go back and troubleshoot that angle.

The second example using the anvil.server.context is just gold. I had not pursued server-side solutions b/c I had read in another thread that server-side IP lookups would show as Anvil’s IPs instead of the actual end user’s IP. Apparently that thread was either outdated or referring to a situation I mistakenly thought resembled my own.

Thank you so much for the reply and suggestions. Either one of your suggestions by themselves would have been a win for me. But two solutions that are also both applicable to a wide range of future projects is the icing on the cake.

Cheers.

2 Likes