Editable capture-coordinates

Use case: procedure is being performed at a particular location. Want to capture this location using capture-coordinates. By default this should populate with the user’s current location and it does. But user may be back-logging the procedure and need to drag the map to the actual location. This is where I’m running into issues as every time the view loads, it seems to overwrite the saved location with the user’s current location. I have tried both using a view var and binding directly to the object field of type location.

View:

<param name="procedure" type="procedure" />
<var name="location" type="location" />
<capture-coordinates allow-dragging="true" allow-zoom="true" on-location="$:updateLocation($value)"  bind="location" />

JS:

function init() {
  view.location = view.procedure.location;
}

function updateLocation(loc) {
    view.location = loc;
    view.procedure.gps_location = loc;
    view.procedure.save();
}

When in the view clicking on a different location in the component works as expected and moves the marker. I then dismiss the view and confirm in the DB that procedure.gps_location was set as expected. And yet when I open the view again, the location is yet again defaulted to my current location which is not the one that was saved to the procedure in the DB.

Help?

I have made some headway after discovering markers, but I now have a new issue where I cannot retrieve the component by id to center it on my procedure’s location.

View:

<?xml version="1.0" encoding="UTF-8"?>
<view title="test_view">
    <param name="procedure" type="procedure" />
    <capture-coordinates allow-dragging="true" allow-zoom="true" on-location="$:updateLocation($value)" id="my-location">
        <marker bind="procedure.gps_location" />
    </capture-coordinates>
</view>

JS:


// This function is called when the user returns to this view from another view
function resume(from) {
  // from.back       (true/false) if true, the user pressed the "Back" button to return to this view
  // from.dismissed  (true/false) if true, the app dismissed to return to this view
  // from.path       contains the path of the view that the user returned from
  // if any data needs to be refreshed when the user returns to this view, you can do that here:
}
function init() {
  if (view.procedure && view.procedure.gps_location) {
    component.captureCoordinates({id: 'my-location'}).setMapState({
        center: view.procedure.gps_location
    });
  }
}

function updateLocation(loc) {
    view.procedure.gps_location = loc;
    view.procedure.save();
}

When I open the view I get a warning in the dev console indicating the component cannot be found:
image

Can’t really make sense of that given it’s clearly there. Also may be worth noting that the setMapState function is producing a warning that it expects 0 arguments?
image

Hi @fthomas,

For your use case it is best to use markers as you have discovered.

The reason why you are getting the error is because the init function executes before the view components have rendered. I would suggest wrapping the setMapState logic inside a setTimeout as shown below. This way, you will allow enough time for the capture-coordinates component to render.

function init() {
    if (view.procedure && view.procedure.gps_location) {
        setTimeout(function() {
            component.captureCoordinates({id: 'my-location'}).setMapState({
                center: view.procedure.gps_location
            });
        }, 100);
    }
}

It is difficult to say what time delay would be enough, though. Please feel free to submit an idea on our product board if you would like to access the capture-coordinates component from the init function without having to use a bit of a hack.

Thank you also for highlighting the issue where OXIDE indicates that 0 arguments are expected. It is just a false warning, so your code should still work as expected. Our team is aware of the issue and will release a fix for it soon.

Thank you this was helpful, one other follow-up question: using the simple “Background” Capturing example, view.current_location is evaluating as undefined when testing from dev console:

image

If I change show to true, the marker is getting dropped at my current location, but for some reason view.current_location still evaluates as undefined. Is it possible to retrieve the location value of a capture-coordinates component prior to a user interacting with it?

As a workaround I see that I could retrieve the component map state and assume that it is centered on the current location (which it should be)

component.captureCoordinates({id: "currloc"}).getMapState().center