- From: Rick Waldron via GitHub <sysbot+gh@w3.org>
- Date: Sun, 06 Mar 2016 21:45:48 +0000
- To: public-device-apis@w3.org
> ... when using addEventListener(), the start() method must also be
invoked. When using onmessage, the call to start() is implied.
I agree this is very unintuitive and we should absolutely avoid this
pattern.
> Seems more clear to require start() for both onreading and
addEventListener('reading', ...), thus the solutions 1 and 2 should
actually be the same. I'd probably name the method simply start().
Not a `start`, because the sensor is born "started" by default. From
there it may only `pause` or `resume`. I don't think these should have
any effect on registering a handler and vice versa. If a program has
called `pause()`, the only way to resume activity is to call `resume`.
Which brings me to...
## Solution 4
**One Shot**
```js
Geolocation.read({ accuracy: "high" }).then(reading =>
findAddress(reading.coords));
```
**Continuous**
```js
let geo = new Geolocation({ accuracy: "high" }); // triggered an
"Allow this app to use location"...
// Call pause() before adding an event handler...
geo.pause();
geo.ondata = event => displayMap(event.data.coords);
// ... or after...
geo.pause();
// ... It doesn't matter because nothing interesting can come from the
geo sensor
// until the next execution turn. Also, it doesn't matter if `ondata =
...` is used or
// `addEventListener`, same behavior
```
I wanted to prove to myself that this was reasonably easy to use in a
real thing, and that real benefit could be derived from it. Using
@ryanflorence's https://github.com/ryanflorence/react-project, I
modified Ryan's default placeholder to have a "Map" view (it's not
really, as you'll see), and a "Home" view. The Map component should
initialize a new, _paused_ Geolocation sensor at runtime, and only
resume it when the Map component is in view. I collected 4 lat/long
points along a path down Atlantic avenue in Brooklyn, to use as data
in a simulation. Here's a video of pause/resume semantics aligned with
React component mounting and unmounting: https://youtu.be/2rU0xudkp5s
Here's the code for for the map component:
```js
import React from "react";
import Geolocation from "./geolocation-simulator";
import { header } from "./styles.css";
import Title from "react-title-component";
let handlers = new Map();
let geo = new Geolocation({ frequency: 4 });
geo.pause();
geo.on("data", coords => {
console.log(`Data Event; received: ${coords.latitude}
${coords.longitude}`);
handlers.forEach(handler => handler(coords));
});
export default React.createClass({
getInitialState() {
return {
latitude: null,
longitude: null,
};
},
componentDidMount() {
geo.resume();
handlers.set(this, coords => {
this.setState({ ...coords });
});
},
componentWillUnmount() {
geo.pause();
handlers.clear();
},
render() {
return (
<div>
<Title render="Map"/>
<h2 className={header}>Longitude & Latitude</h2>
<ul>
<li>Latitude: {this.state.latitude}</li>
<li>Longitude: {this.state.longitude}</li>
</ul>
</div>
)
}
});
```
(Also,
[here](https://gist.github.com/rwaldron/982f91c96d3af5c18395#file-map-component-index-js))
Here's a similar thing, that only gets the coords once, but it's nice
to show how the one-shot looks in action:
```js
import React from "react";
import Geolocation from "./geolocation-simulator";
import { header } from "./styles.css";
import Title from "react-title-component";
export default React.createClass({
getInitialState() {
return {
latitude: null,
longitude: null,
};
},
componentDidMount() {
Geolocation.read().then(coords => {
let {latitude, longitude} = coords;
this.setState({ ...coords });
});
},
render() {
return (
<div>
<Title render="Map"/>
<h2 className={header}>Longitude & Latitude</h2>
<ul>
<li>Latitude: {this.state.latitude}</li>
<li>Longitude: {this.state.longitude}</li>
</ul>
</div>
)
}
});
```
--
GitHub Notification of comment by rwaldron
Please view or discuss this issue at
https://github.com/w3c/sensors/issues/88#issuecomment-193002528 using
your GitHub account
Received on Sunday, 6 March 2016 21:45:51 UTC