Skip to content

Commit f85f9d7

Browse files
committed
Cleaner two-way binding
1 parent 74ec324 commit f85f9d7

File tree

1 file changed

+37
-39
lines changed

1 file changed

+37
-39
lines changed

examples/airmass/location.py

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,13 @@ def location_server(
3636
input: Inputs, output: Outputs, session: Session, *, wrap_long: bool = True
3737
):
3838
map = L.Map(center=(0, 0), zoom=1, scoll_wheel_zoom=True)
39-
marker = L.Marker(location=(52, 100))
39+
with reactive.isolate():
40+
marker = L.Marker(location=(input.lat() or 0, input.long() or 0))
4041

41-
@reactive.Effect
42-
@reactive.isolate() # Use this to ensure we only execute one time
43-
def _():
42+
with reactive.isolate(): # Use this to ensure we only execute one time
4443
if input.lat() is None and input.long() is None:
4544
ui.notification_show(
46-
"Searching for location...", duration=False, id="searching"
45+
"Searching for location...", duration=99999, id="searching"
4746
)
4847
ui.insert_ui(
4948
ui.tags.script(
@@ -67,56 +66,55 @@ def _():
6766
immediate=True,
6867
)
6968

70-
def move(lat: float, long: float) -> None:
69+
@reactive.isolate()
70+
def update_text_inputs(lat: Optional[float], long: Optional[float]) -> None:
71+
req(lat is not None, long is not None)
7172
lat = round(lat, 8)
7273
long = round(long, 8)
73-
marker.location = (lat, long)
74+
if lat != input.lat():
75+
input.lat.freeze()
76+
ui.update_text("lat", value=lat)
77+
if long != input.long():
78+
input.long.freeze()
79+
ui.update_text("long", value=long)
80+
map.center = (lat, long)
81+
82+
@reactive.isolate()
83+
def update_marker(lat: Optional[float], long: Optional[float]) -> None:
84+
req(lat is not None, long is not None)
85+
lat = round(lat, 8)
86+
long = round(long, 8)
87+
if marker.location != (lat, long):
88+
marker.location = (lat, long)
7489
if marker not in map.layers:
7590
map.add_layer(marker)
76-
ui.update_text("lat", value=lat)
77-
ui.update_text("long", value=long)
91+
map.center = marker.location
7892

7993
def on_map_interaction(**kwargs):
8094
if kwargs.get("type") == "click":
81-
coords = kwargs.get("coordinates")
82-
move(coords[0], coords[1])
95+
lat, long = kwargs.get("coordinates")
96+
update_text_inputs(lat, long)
8397

8498
map.on_interaction(on_map_interaction)
8599

86-
def on_marker_move():
87-
move(marker.location[0], marker.location[1])
88-
89-
marker.on_move(on_marker_move)
90-
91100
register_widget("map", map)
92101

93102
@reactive.Effect
94-
def detect_location():
103+
def _():
104+
coords = reactive_read(marker, "location")
105+
if coords:
106+
update_text_inputs(coords[0], coords[1])
107+
108+
@reactive.Effect
109+
def sync_autolocate():
95110
coords = input.here()
96111
ui.notification_remove("searching")
97112
if coords and not input.lat() and not input.long():
98-
ui.update_numeric("lat", value=coords["latitude"])
99-
ui.update_numeric("long", value=coords["longitude"])
113+
update_text_inputs(coords["latitude"], coords["longitude"])
100114

101115
@reactive.Effect
102-
def sync_map_lat():
103-
req(input.lat() is not None)
104-
lat = float(input.lat())
105-
if marker.location[0] != lat:
106-
marker.location = (lat, marker.location[1])
107-
if marker not in map.layers:
108-
map.add_layer(marker)
109-
map.center = marker.location
110-
111-
@reactive.Effect
112-
def sync_map_long():
113-
req(input.long() is not None)
114-
long = float(input.long())
115-
if marker.location[1] != long:
116-
marker.location = (marker.location[0], long)
117-
if marker not in map.layers:
118-
map.add_layer(marker)
119-
map.center = marker.location
116+
def sync_inputs_to_marker():
117+
update_marker(input.lat(), input.long())
120118

121119
@reactive.Calc
122120
def location():
@@ -127,11 +125,11 @@ def location():
127125
req(input.lat() is not None, input.long() is not None)
128126

129127
try:
130-
long = float(input.long())
128+
long = input.long()
131129
# Wrap longitudes so they're within [-180, 180]
132130
if wrap_long:
133131
long = (long + 180) % 360 - 180
134-
return (float(input.lat()), long)
132+
return (input.lat(), long)
135133
except ValueError:
136134
raise ValueError("Invalid latitude/longitude specification")
137135

0 commit comments

Comments
 (0)